diff options
| author | Berke Güzel <wenekar1@gmail.com> | 2026-10-15 11:37:31 +0300 |
|---|---|---|
| committer | Berke Güzel <wenekar1@gmail.com> | 2026-10-15 11:37:31 +0300 |
| commit | af6a37b1c4509c7766933a7cb45d2ee9a3a23f98 (patch) | |
| tree | e7b0294ebf0d9b124b8885a76c119d7f46d5b0fb | |
| parent | acd338ea33de36d223cc6d301712eed4a9501e6c (diff) | |
Return owned text and share cell attribute flags with snapshots
Make text queries return allocated strings released with term_text_free, keeping each capture atomic. Align public attributes with the write core, remove snapshot conversion tables, and migrate tests and the Kitty adapter.
| -rw-r--r-- | include/term/term.h | 77 | ||||
| -rw-r--r-- | src/cell.h | 30 | ||||
| -rw-r--r-- | src/internal.h | 15 | ||||
| -rw-r--r-- | src/screen.c | 1 | ||||
| -rw-r--r-- | src/selection.c | 29 | ||||
| -rw-r--r-- | src/snapshot.c | 34 | ||||
| -rw-r--r-- | src/term.c | 23 | ||||
| -rw-r--r-- | src/text_run.h | 1 | ||||
| -rw-r--r-- | tests/extern/kitty/screen.py | 14 | ||||
| -rw-r--r-- | tests/helpers/term_api.h | 23 | ||||
| -rw-r--r-- | tests/model.c | 11 | ||||
| -rw-r--r-- | tests/osc_test.c | 10 | ||||
| -rw-r--r-- | tests/spec_test.c | 2 | ||||
| -rw-r--r-- | tests/term_test.c | 11 |
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 @@ -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, }; } @@ -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); } |
