summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/term/term.h77
-rw-r--r--src/cell.h30
-rw-r--r--src/internal.h15
-rw-r--r--src/screen.c1
-rw-r--r--src/selection.c29
-rw-r--r--src/snapshot.c34
-rw-r--r--src/term.c23
-rw-r--r--src/text_run.h1
-rw-r--r--tests/extern/kitty/screen.py14
-rw-r--r--tests/helpers/term_api.h23
-rw-r--r--tests/model.c11
-rw-r--r--tests/osc_test.c10
-rw-r--r--tests/spec_test.c2
-rw-r--r--tests/term_test.c11
14 files changed, 109 insertions, 172 deletions
diff --git a/include/term/term.h b/include/term/term.h
index 9c6281b..dc41114 100644
--- a/include/term/term.h
+++ b/include/term/term.h
@@ -11,8 +11,9 @@
* paints from that copy.
*
* All functions take the terminal as the first argument. Functions that take
- * a const struct term do not change what it shows. A function that returns
- * text copies it into a buffer that the caller owns.
+ * a const struct term do not change what it shows. Selection, history, link,
+ * directory, and pointer-shape queries return owned strings; release them
+ * with term_text_free().
*
* Threads. Any thread can call any function. Each call that reads or changes
* a terminal enters its writer section, so calls on one terminal run one at a
@@ -262,11 +263,13 @@ TERM_API struct term_input_result term_input_encode_paste(
);
/* The cursor in screen coordinates (not the viewport). */
TERM_API struct term_cursor term_cursor(const struct term *t);
-/* Copy the directory from OSC 7 into buf, with the rules of
- * term_selection_text(). Return 0 when there is none. */
-TERM_API size_t term_cwd(const struct term *t, char *buf, size_t cap);
-/* Copy the pointer shape name from OSC 22 the same way. */
-TERM_API size_t term_pointer_shape(const struct term *t, char *buf, size_t cap);
+/* Owned, NUL-terminated text from OSC 7 and OSC 22. NULL when unavailable
+ * or allocation fails. The strings stay valid after the terminal changes
+ * or is freed. Release them with term_text_free(). */
+TERM_API char *term_cwd(const struct term *t);
+TERM_API char *term_pointer_shape(const struct term *t);
+/* Release any owned text returned by the library. NULL is safe. */
+TERM_API void term_text_free(char *text);
/*
* Viewport. The viewport shows as many rows as the screen. Offset 0 shows
@@ -302,30 +305,36 @@ TERM_API void term_select_start(struct term *t, struct term_vector2i cell, bool
TERM_API void term_select_extend(struct term *t, struct term_vector2i cell, bool right_half);
TERM_API void term_select_clear(struct term *t);
TERM_API bool term_has_selection(const struct term *t);
-/* Copy the selected text as UTF-8 into buf. Return its length without the NUL.
- * With a NULL buf or a zero cap, only the length is returned. Otherwise the
- * copy is cut to cap - 1 bytes and NUL-terminated. Return 0 when nothing is
- * selected. Hold term_lock across the length query and the copy to keep the
- * length stable. */
-TERM_API size_t term_selection_text(const struct term *t, char *buf, size_t cap);
-/* The OSC 8 link or the detected URL at a viewport cell. Copies it with the
- * same rules as term_selection_text(). Return 0 when there is no link. */
-TERM_API size_t term_link_at(const struct term *t, struct term_vector2i cell, char *buf, size_t cap);
-
-/* Cell attributes. */
+/* Owned, NUL-terminated UTF-8 of the selection. NULL when nothing is
+ * selected or allocation fails; a selection of blanks may produce an empty
+ * string. Capture is atomic with respect to other calls on t. Release the
+ * result with term_text_free(). */
+TERM_API char *term_selection_text(const struct term *t);
+/* Owned OSC 8 link or detected URL at a viewport cell. NULL when there is
+ * no link or allocation fails. Release the result with term_text_free(). */
+TERM_API char *term_link_at(const struct term *t, struct term_vector2i cell);
+
+/* Cell attributes share the write core's bit layout. Underline styles are
+ * mutually exclusive flags, not a shifted enum; use term_attr_underline(). */
enum term_attr {
TERM_ATTR_BOLD = 1u << 0,
TERM_ATTR_ITALIC = 1u << 1,
- TERM_ATTR_FAINT = 1u << 2,
+ TERM_ATTR_UNDERLINE = 1u << 2,
TERM_ATTR_STRIKE = 1u << 3,
TERM_ATTR_OVERLINE = 1u << 4,
- TERM_ATTR_LINK = 1u << 5,
- TERM_ATTR_EMOJI = 1u << 6, /* the text requested emoji presentation */
- TERM_ATTR_TEXT = 1u << 7, /* the text requested text presentation */
+ TERM_ATTR_EMOJI = 1u << 5, /* the text requested emoji presentation */
+ TERM_ATTR_TEXT = 1u << 6, /* the text requested text presentation */
+ TERM_ATTR_FAINT = 1u << 10,
+ TERM_ATTR_DOUBLE_UNDERLINE = 1u << 11,
+ TERM_ATTR_CURLY_UNDERLINE = 1u << 12,
+ TERM_ATTR_DOTTED_UNDERLINE = 1u << 13,
+ TERM_ATTR_DASHED_UNDERLINE = 1u << 14,
+ TERM_ATTR_LINK = 1u << 15,
};
-#define TERM_ATTR_UNDERLINE_SHIFT 8
-#define TERM_ATTR_UNDERLINE_MASK (7u << TERM_ATTR_UNDERLINE_SHIFT)
+#define TERM_ATTR_UNDERLINE_MASK \
+ (TERM_ATTR_UNDERLINE | TERM_ATTR_DOUBLE_UNDERLINE | TERM_ATTR_CURLY_UNDERLINE | \
+ TERM_ATTR_DOTTED_UNDERLINE | TERM_ATTR_DASHED_UNDERLINE)
enum term_underline {
TERM_UNDERLINE_NONE,
@@ -338,7 +347,11 @@ enum term_underline {
static inline enum term_underline term_attr_underline(uint16_t attrs)
{
- return (enum term_underline)((attrs & TERM_ATTR_UNDERLINE_MASK) >> TERM_ATTR_UNDERLINE_SHIFT);
+ if (attrs & TERM_ATTR_DOUBLE_UNDERLINE) return TERM_UNDERLINE_DOUBLE;
+ if (attrs & TERM_ATTR_CURLY_UNDERLINE) return TERM_UNDERLINE_CURLY;
+ if (attrs & TERM_ATTR_DOTTED_UNDERLINE) return TERM_UNDERLINE_DOTTED;
+ if (attrs & TERM_ATTR_DASHED_UNDERLINE) return TERM_UNDERLINE_DASHED;
+ return attrs & TERM_ATTR_UNDERLINE ? TERM_UNDERLINE_SINGLE : TERM_UNDERLINE_NONE;
}
/* text refers to a grapheme cluster in the snapshot; see term_snapshot_cluster(). */
@@ -348,7 +361,7 @@ static inline enum term_underline term_attr_underline(uint16_t attrs)
struct term_cell {
uint32_t text; /* a code point, TERM_TEXT_CLUSTER | n, or 0 for an empty cell */
term_color fg, bg;
- uint16_t attrs; /* enum term_attr and the underline style */
+ uint16_t attrs; /* enum term_attr flags; at most one underline flag */
uint8_t width; /* 1; 2 for a wide glyph; 0 for the right half of a wide glyph */
uint8_t reserved;
};
@@ -404,12 +417,12 @@ TERM_API uint64_t term_snapshot_row_key(const struct term_snapshot *s, int y);
/* Number of rows in history above the screen. 0 if alternate screen or no history. */
TERM_API int term_history_rows(const struct term *t);
-/* Copy up to max_rows history rows before the current viewport as UTF-8 into
- * buf, with the same rules as term_selection_text(). Join soft-wrapped rows.
- * End closed lines with a newline. This does not change the selection.
- * Return 0 when there is no history text, and also when the text cannot be
- * built. */
-TERM_API size_t term_history_text(struct term *t, int max_rows, char *buf, size_t cap);
+/* Owned, NUL-terminated UTF-8 of up to max_rows history rows before the
+ * current viewport. Join soft-wrapped rows and end closed lines with a
+ * newline. Does not change the selection. No history or max_rows <= 0 gives
+ * an empty string; NULL means allocation failed or t is NULL. Release the
+ * result with term_text_free(). */
+TERM_API char *term_history_text(struct term *t, int max_rows);
TERM_API struct term_span term_snapshot_row_selection(const struct term_snapshot *s, int y);
/* The code points of a cluster cell. Returns the number of code points and
diff --git a/src/cell.h b/src/cell.h
index 41b16eb..615879e 100644
--- a/src/cell.h
+++ b/src/cell.h
@@ -9,27 +9,25 @@
#include "term.h"
enum cell_flags {
- CELL_BOLD = 1 << 0,
- CELL_ITALIC = 1 << 1,
- CELL_UNDERLINE = 1 << 2,
- CELL_STRIKE = 1 << 3,
- CELL_OVERLINE = 1 << 4,
- CELL_EMOJI = 1 << 5,
- CELL_TEXT = 1 << 6,
+ CELL_BOLD = TERM_ATTR_BOLD,
+ CELL_ITALIC = TERM_ATTR_ITALIC,
+ CELL_UNDERLINE = TERM_ATTR_UNDERLINE,
+ CELL_STRIKE = TERM_ATTR_STRIKE,
+ CELL_OVERLINE = TERM_ATTR_OVERLINE,
+ CELL_EMOJI = TERM_ATTR_EMOJI,
+ CELL_TEXT = TERM_ATTR_TEXT,
CELL_WIDE = 1 << 7,
CELL_TRAIL = 1 << 8,
CELL_WRAP_PAD = 1 << 9,
- CELL_FAINT = 1 << 10,
- CELL_DOUBLE_UNDERLINE = 1 << 11,
- CELL_CURLY_UNDERLINE = 1 << 12,
- CELL_DOTTED_UNDERLINE = 1 << 13,
- CELL_DASHED_UNDERLINE = 1 << 14,
- CELL_LINK = 1 << 15,
+ CELL_FAINT = TERM_ATTR_FAINT,
+ CELL_DOUBLE_UNDERLINE = TERM_ATTR_DOUBLE_UNDERLINE,
+ CELL_CURLY_UNDERLINE = TERM_ATTR_CURLY_UNDERLINE,
+ CELL_DOTTED_UNDERLINE = TERM_ATTR_DOTTED_UNDERLINE,
+ CELL_DASHED_UNDERLINE = TERM_ATTR_DASHED_UNDERLINE,
+ CELL_LINK = TERM_ATTR_LINK,
};
-#define CELL_ANY_UNDERLINE \
- (CELL_UNDERLINE | CELL_DOUBLE_UNDERLINE | CELL_CURLY_UNDERLINE | \
- CELL_DOTTED_UNDERLINE | CELL_DASHED_UNDERLINE)
+#define CELL_ANY_UNDERLINE TERM_ATTR_UNDERLINE_MASK
/* c is a code point or a grapheme handle. pad holds the OSC 8 link id. */
struct cell {
diff --git a/src/internal.h b/src/internal.h
index d823018..8c02c91 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -364,21 +364,6 @@ static inline bool term_str_was_truncated(struct term *t)
return truncated;
}
-/* Copy text into buf with the rules of term_selection_text(). NULL text
- * copies as empty. Return the full length. */
-static inline size_t term_copy_out(const char *text, char *buf, size_t cap)
-{
- if (!text)
- text = "";
- size_t n = strlen(text);
- if (buf && cap) {
- size_t k = n < cap ? n : cap - 1;
- if (k) memcpy(buf, text, k);
- buf[k] = '\0';
- }
- return n;
-}
-
/* Every thread has its own anchor, so its address names the thread. */
extern _Thread_local char term_thread_anchor;
diff --git a/src/screen.c b/src/screen.c
index 1712faf..87d6f2c 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -829,7 +829,6 @@ static void tables_init(void)
if (atomic_compare_exchange_strong(&tables_state, &expected, 1)) {
term_isa_init();
term_text_tables_init();
- term_snapshot_tables_init();
atomic_store_explicit(&tables_state, 2, memory_order_release);
return;
}
diff --git a/src/selection.c b/src/selection.c
index 2727e8a..3ac2ee3 100644
--- a/src/selection.c
+++ b/src/selection.c
@@ -5,14 +5,6 @@
#include <stdlib.h>
#include <string.h>
-/* Copies a heap string into buf and frees it. Returns the length without the NUL. */
-static size_t text_out(char *text, char *buf, size_t cap)
-{
- size_t n = term_copy_out(text, buf, cap);
- free(text);
- return n;
-}
-
static char *link_at_text(const struct term *t, struct term_vector2i cell)
{
int col = cell.x, row = cell.y;
@@ -62,14 +54,13 @@ static char *link_at_text(const struct term *t, struct term_vector2i cell)
return out;
}
-size_t term_link_at(const struct term *t, struct term_vector2i cell, char *buf, size_t cap)
+char *term_link_at(const struct term *t, struct term_vector2i cell)
{
- if (!t)
- return 0;
+ if (!t) return NULL;
term_write_begin((struct term *)t);
char *text = link_at_text(t, cell);
term_write_end((struct term *)t);
- return text_out(text, buf, cap);
+ return text;
}
void term_select_clear(struct term *t)
@@ -775,7 +766,7 @@ static char *range_text_inner(const struct term *t,
return text;
}
-static char *history_text(struct term *t, int max_rows)
+char *term_history_text(struct term *t, int max_rows)
{
if (!t)
return NULL;
@@ -822,17 +813,11 @@ static char *history_text(struct term *t, int max_rows)
return text;
}
-size_t term_history_text(struct term *t, int max_rows, char *buf, size_t cap)
+char *term_selection_text(const struct term *t)
{
- return text_out(history_text(t, max_rows), buf, cap);
-}
-
-size_t term_selection_text(const struct term *t, char *buf, size_t cap)
-{
- if (!t)
- return 0;
+ if (!t) return NULL;
term_write_begin((struct term *)t);
char *text = range_text_inner(t, NULL);
term_write_end((struct term *)t);
- return text_out(text, buf, cap);
+ return text;
}
diff --git a/src/snapshot.c b/src/snapshot.c
index 6578c9a..8dbb498 100644
--- a/src/snapshot.c
+++ b/src/snapshot.c
@@ -87,33 +87,6 @@ static void invalidate(struct term_snapshot *s)
}
}
-/* Attribute contributions of the low and high byte of cell flags. */
-static uint16_t lo_attrs[256], hi_attrs[256];
-static uint8_t hi_underline[256];
-void term_snapshot_tables_init(void)
-{
- for (int b = 0; b < 256; b++) {
- uint16_t lo = 0, hi = 0;
- if (b & CELL_BOLD) lo |= TERM_ATTR_BOLD;
- if (b & CELL_ITALIC) lo |= TERM_ATTR_ITALIC;
- if (b & CELL_STRIKE) lo |= TERM_ATTR_STRIKE;
- if (b & CELL_OVERLINE) lo |= TERM_ATTR_OVERLINE;
- if (b & CELL_EMOJI) lo |= TERM_ATTR_EMOJI;
- if (b & CELL_TEXT) lo |= TERM_ATTR_TEXT;
- uint16_t f = (uint16_t)(b << 8);
- if (f & CELL_FAINT) hi |= TERM_ATTR_FAINT;
- if (f & CELL_LINK) hi |= TERM_ATTR_LINK;
- uint8_t ul = 0;
- if (f & CELL_DOUBLE_UNDERLINE) ul = TERM_UNDERLINE_DOUBLE;
- else if (f & CELL_CURLY_UNDERLINE) ul = TERM_UNDERLINE_CURLY;
- else if (f & CELL_DOTTED_UNDERLINE) ul = TERM_UNDERLINE_DOTTED;
- else if (f & CELL_DASHED_UNDERLINE) ul = TERM_UNDERLINE_DASHED;
- lo_attrs[b] = lo;
- hi_attrs[b] = hi;
- hi_underline[b] = ul;
- }
-}
-
static uint32_t arena_add(struct term_snapshot *s, const struct gstore *g, uint32_t handle,
bool *ok)
{
@@ -148,10 +121,6 @@ static uint32_t convert_row(struct term_snapshot *s, const struct gstore *g,
for (int x = 0; x < cols; x++) {
const struct cell *c = &src[x];
uint16_t f = c->flags;
- uint8_t lo = (uint8_t)f, hi = (uint8_t)(f >> 8);
- uint16_t ul = hi_underline[hi];
- if (!ul && (f & CELL_UNDERLINE))
- ul = TERM_UNDERLINE_SINGLE;
uint32_t text = c->c;
if (TERM_EXPECT(text < 0x20, 0))
text = text ? ' ' : 0;
@@ -164,8 +133,7 @@ static uint32_t convert_row(struct term_snapshot *s, const struct gstore *g,
.text = text,
.fg = c->fg,
.bg = c->bg,
- .attrs = (uint16_t)(lo_attrs[lo] | hi_attrs[hi] |
- ul << TERM_ATTR_UNDERLINE_SHIFT),
+ .attrs = (uint16_t)(f & ~(CELL_WIDE | CELL_TRAIL | CELL_WRAP_PAD)),
.width = (f & CELL_TRAIL) ? 0 : (f & CELL_WIDE) ? 2 : 1,
};
}
diff --git a/src/term.c b/src/term.c
index 583bdd8..1b16670 100644
--- a/src/term.c
+++ b/src/term.c
@@ -104,22 +104,25 @@ void term_focus(struct term *t, bool focused)
term_write_end(t);
}
-size_t term_cwd(const struct term *t, char *buf, size_t cap)
+char *term_cwd(const struct term *t)
{
- if (!t)
- return term_copy_out(NULL, buf, cap);
+ if (!t) return NULL;
term_write_begin((struct term *)t);
- size_t n = term_copy_out(t->cwd, buf, cap);
+ char *text = t->cwd ? term_strdup(t->cwd) : NULL;
term_write_end((struct term *)t);
- return n;
+ return text;
}
-size_t term_pointer_shape(const struct term *t, char *buf, size_t cap)
+char *term_pointer_shape(const struct term *t)
{
- if (!t)
- return term_copy_out(NULL, buf, cap);
+ if (!t) return NULL;
term_write_begin((struct term *)t);
- size_t n = term_copy_out(t->pointer_shape, buf, cap);
+ char *text = t->pointer_shape ? term_strdup(t->pointer_shape) : NULL;
term_write_end((struct term *)t);
- return n;
+ return text;
+}
+
+void term_text_free(char *text)
+{
+ free(text);
}
diff --git a/src/text_run.h b/src/text_run.h
index d546062..fac638f 100644
--- a/src/text_run.h
+++ b/src/text_run.h
@@ -21,7 +21,6 @@ struct width_cache {
/* term_new() builds the shared tables before any terminal can use them. */
bool term_tables_ready(void);
void term_text_tables_init(void);
-void term_snapshot_tables_init(void);
int term_text_class(uint32_t cp);
diff --git a/tests/extern/kitty/screen.py b/tests/extern/kitty/screen.py
index cc7289b..a3336d8 100644
--- a/tests/extern/kitty/screen.py
+++ b/tests/extern/kitty/screen.py
@@ -71,14 +71,13 @@ TERM_DEFAULT_BG = 0xFF1E1E2E
# Cell attributes (must match enum term_attr in term.h)
TERM_ATTR_BOLD = 1 << 0
TERM_ATTR_ITALIC = 1 << 1
-TERM_ATTR_FAINT = 1 << 2
+TERM_ATTR_FAINT = 1 << 10
TERM_ATTR_STRIKE = 1 << 3
TERM_ATTR_OVERLINE = 1 << 4
-TERM_ATTR_LINK = 1 << 5
-TERM_ATTR_EMOJI = 1 << 6
-TERM_ATTR_TEXT = 1 << 7
-TERM_ATTR_UNDERLINE_SHIFT = 8
-TERM_ATTR_UNDERLINE_MASK = 7 << TERM_ATTR_UNDERLINE_SHIFT
+TERM_ATTR_LINK = 1 << 15
+TERM_ATTR_EMOJI = 1 << 5
+TERM_ATTR_TEXT = 1 << 6
+TERM_UNDERLINE_FLAGS = (1 << 2, 1 << 11, 1 << 12, 1 << 13, 1 << 14)
# The longest grapheme cluster that a cell's text is read with.
_CLUSTER_CAP = 32
@@ -276,7 +275,8 @@ class CellCursor:
def decoration(self):
# enum term_underline uses Kitty's numbers: 0=none, 1=straight,
# 2=double, 3=curly, 4=dotted, 5=dashed.
- return (self._cell.attrs & TERM_ATTR_UNDERLINE_MASK) >> TERM_ATTR_UNDERLINE_SHIFT
+ return next((i for i, flag in enumerate(TERM_UNDERLINE_FLAGS, 1)
+ if self._cell.attrs & flag), 0)
@property
def fg(self):
diff --git a/tests/helpers/term_api.h b/tests/helpers/term_api.h
index bfa8d71..f2d6a5d 100644
--- a/tests/helpers/term_api.h
+++ b/tests/helpers/term_api.h
@@ -137,35 +137,18 @@ static inline void tt_select(struct term *t, int x1, int y1, int x2, int y2)
/* NULL when nothing is selected. */
static inline char *tt_selection_text(const struct term *t)
{
- size_t n = term_selection_text(t, NULL, 0);
- if (!n)
- return NULL;
- char *text = malloc(n + 1);
- if (text)
- term_selection_text(t, text, n + 1);
- return text;
+ return term_selection_text(t);
}
static inline char *tt_history_text(struct term *t, int max_rows)
{
- size_t n = term_history_text(t, max_rows, NULL, 0);
- char *text = malloc(n + 1);
- if (text)
- term_history_text(t, max_rows, text, n + 1);
- return text;
+ return term_history_text(t, max_rows);
}
/* NULL when there is no link. */
static inline char *tt_link_at(struct term *t, int col, int row)
{
- struct term_vector2i cell = { .x = col, .y = row };
- size_t n = term_link_at(t, cell, NULL, 0);
- if (!n)
- return NULL;
- char *url = malloc(n + 1);
- if (url)
- term_link_at(t, cell, url, n + 1);
- return url;
+ return term_link_at(t, (struct term_vector2i){ .x = col, .y = row });
}
static inline bool tt_resize(struct term *t, int cols, int rows)
diff --git a/tests/model.c b/tests/model.c
index 4fd3737..8dead6c 100644
--- a/tests/model.c
+++ b/tests/model.c
@@ -727,9 +727,12 @@ static void pen_reset(struct pen *p)
static void set_underline(uint16_t *attrs, int style)
{
- if (style > 5) style = 1;
- *attrs = (uint16_t)((*attrs & ~TERM_ATTR_UNDERLINE_MASK) |
- (unsigned)style << TERM_ATTR_UNDERLINE_SHIFT);
+ static const uint16_t flags[] = {
+ 0, TERM_ATTR_UNDERLINE, TERM_ATTR_DOUBLE_UNDERLINE,
+ TERM_ATTR_CURLY_UNDERLINE, TERM_ATTR_DOTTED_UNDERLINE, TERM_ATTR_DASHED_UNDERLINE,
+ };
+ if ((unsigned)style > 5) style = 1;
+ *attrs = (uint16_t)((*attrs & ~TERM_ATTR_UNDERLINE_MASK) | flags[style]);
}
/* 38, 48, and 58. Returns the parameters it used after the first. */
@@ -814,7 +817,7 @@ static void sgr_report(const struct model *m, char *out, size_t cap)
size_t n = 0;
out[0] = 0;
#define ADD(...) do { int k = snprintf(out + n, cap - n, __VA_ARGS__); if (k > 0) n += (size_t)k; } while (0)
- int ul = (int)((p->attrs & TERM_ATTR_UNDERLINE_MASK) >> TERM_ATTR_UNDERLINE_SHIFT);
+ int ul = term_attr_underline(p->attrs);
if (!(p->attrs & (TERM_ATTR_BOLD | TERM_ATTR_FAINT | TERM_ATTR_ITALIC | TERM_ATTR_STRIKE |
TERM_ATTR_OVERLINE | TERM_ATTR_UNDERLINE_MASK)) &&
!p->inverse && p->fg == TERM_COLOR_FG && p->bg == TERM_COLOR_BG && !p->ul)
diff --git a/tests/osc_test.c b/tests/osc_test.c
index 91b51d6..41a9247 100644
--- a/tests/osc_test.c
+++ b/tests/osc_test.c
@@ -259,11 +259,13 @@ static void test_osc8(void)
term_free(t);
}
-static bool text_is(size_t (*get)(const struct term *, char *, size_t),
+static bool text_is(char *(*get)(const struct term *),
const struct term *t, const char *want)
{
- char buf[256];
- return get(t, buf, sizeof(buf)) == strlen(want) && !strcmp(buf, want);
+ char *text = get(t);
+ bool same = text && !strcmp(text, want);
+ term_text_free(text);
+ return same;
}
static void test_osc_misc(void)
@@ -304,7 +306,7 @@ static void test_osc_misc(void)
write_seq(t, "\033]22;text\007");
assert(text_is(term_pointer_shape, t, "text"));
write_seq(t, "\033]22;\033\\");
- assert(!term_pointer_shape(t, NULL, 0));
+ assert(!term_pointer_shape(t));
term_free(t);
}
diff --git a/tests/spec_test.c b/tests/spec_test.c
index ec9d45d..202f9ba 100644
--- a/tests/spec_test.c
+++ b/tests/spec_test.c
@@ -175,7 +175,7 @@ static const struct spec cases[] = {
.cols = 8, .rows = 3, ROWS3("X", "", ""), AT(1, 0),
.attr_x = 0, .attr_y = 0,
.attrs = TERM_ATTR_BOLD | TERM_ATTR_ITALIC | TERM_ATTR_STRIKE |
- TERM_ATTR_OVERLINE | (TERM_UNDERLINE_SINGLE << TERM_ATTR_UNDERLINE_SHIFT),
+ TERM_ATTR_OVERLINE | TERM_ATTR_UNDERLINE,
.fg = TERM_COLOR_SLOT | 123, .bg = 0xff010203u, .history = -1,
},
{
diff --git a/tests/term_test.c b/tests/term_test.c
index 3721720..66dbd96 100644
--- a/tests/term_test.c
+++ b/tests/term_test.c
@@ -1811,16 +1811,15 @@ static void test_concurrent_feed_and_snapshot(void)
(void)c;
/* Every reader is safe while another thread feeds. */
- char buf[256];
term_select_start(t, (struct term_vector2i){ .x = 0, .y = 0 }, false, TERM_SELECT_WORD);
term_select_extend(t, (struct term_vector2i){ .x = 40, .y = 10 }, false);
(void)term_has_selection(t);
- (void)term_selection_text(t, buf, sizeof(buf));
- (void)term_link_at(t, (struct term_vector2i){ .x = 1, .y = 1 }, buf, sizeof(buf));
- (void)term_cwd(t, buf, sizeof(buf));
- (void)term_pointer_shape(t, buf, sizeof(buf));
+ term_text_free(term_selection_text(t));
+ term_text_free(term_link_at(t, (struct term_vector2i){ .x = 1, .y = 1 }));
+ term_text_free(term_cwd(t));
+ term_text_free(term_pointer_shape(t));
(void)term_history_rows(t);
- (void)term_history_text(t, 5, buf, sizeof(buf));
+ term_text_free(term_history_text(t, 5));
struct term_scrollback sb = term_scrollback(t);
assert(sb.offset >= 0 && sb.total >= 0);
}