diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/meson.build | 6 | ||||
| -rw-r--r-- | src/screen.c | 22 | ||||
| -rw-r--r-- | src/snapshot.c | 14 | ||||
| -rw-r--r-- | src/term.c | 5 | ||||
| -rw-r--r-- | src/text.c | 14 |
5 files changed, 40 insertions, 21 deletions
diff --git a/src/meson.build b/src/meson.build index 694ee0e..7223caa 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,5 +1,9 @@ subdir('osc') +# The SONAME carries the major version. An ABI break bumps it, so an old +# binary keeps the old library. +term_soversion = meson.project_version().split('.')[0] + # The x86-64 SIMD kernels pick their level at run time (see simd.h), so the # library needs no ISA flags. -march in c_args sets the lowest level. term_lib = both_libraries('term', @@ -23,6 +27,8 @@ term_lib = both_libraries('term', include_directories: term_private_inc, dependencies: [m_dep], gnu_symbol_visibility: 'hidden', + version: meson.project_version(), + soversion: term_soversion, install: true ) diff --git a/src/screen.c b/src/screen.c index e728cec..0857f17 100644 --- a/src/screen.c +++ b/src/screen.c @@ -808,12 +808,11 @@ void term_screen_set_alternate(struct term *t, bool enabled) } } +/* The caller has checked that requested is not negative. */ static int scrollback_lines(int requested) { if (requested == 0) return TERM_SCROLLBACK_DEFAULT; - if (requested < 0) - return 0; return requested > 1000000 ? 1000000 : requested; } @@ -858,13 +857,18 @@ struct term *term_new(const struct term_options *opt) static const struct term_options defaults; if (!opt) opt = &defaults; + for (size_t i = 0; i < sizeof(opt->reserved) / sizeof(opt->reserved[0]); i++) + if (opt->reserved[i]) + return NULL; + if (opt->size.x < 0 || opt->size.y < 0 || opt->size.x > TERM_MAX_COLS) + return NULL; + if (opt->scrollback < 0 || (unsigned)opt->cursor_style > TERM_CURSOR_BAR) + return NULL; const char *name = opt->name && *opt->name ? opt->name : "term"; if (!name_valid(name)) return NULL; - int cols = opt->size.x < 1 ? 80 : opt->size.x; - int rows = opt->size.y < 1 ? 24 : opt->size.y; - if (cols > TERM_MAX_COLS) - cols = TERM_MAX_COLS; + int cols = opt->size.x == 0 ? 80 : opt->size.x; + int rows = opt->size.y == 0 ? 24 : opt->size.y; static _Atomic uint64_t next_serial = 1; struct term *t = calloc(1, sizeof(*t)); @@ -910,7 +914,7 @@ struct term *term_new(const struct term_options *opt) t->cur_fg = TERM_COLOR_FG; t->cur_bg = TERM_COLOR_BG; t->cursor_visible = true; - t->default_cursor_style = opt->cursor_style > TERM_CURSOR_BAR ? TERM_CURSOR_BLOCK : opt->cursor_style; + t->default_cursor_style = opt->cursor_style; t->default_cursor_blink = !opt->cursor_steady; t->cursor_style = t->default_cursor_style; t->cursor_blink = t->default_cursor_blink; @@ -1538,10 +1542,8 @@ bool term_resize(struct term *t, struct term_vector2i size) return false; int cols = size.x; int rows = size.y; - if (cols < 1 || rows < 1) + if (cols < 1 || rows < 1 || cols > TERM_MAX_COLS) return false; - if (cols > TERM_MAX_COLS) - cols = TERM_MAX_COLS; term_write_begin(t); if (cols == t->cols && rows == t->rows) { term_write_end(t); diff --git a/src/snapshot.c b/src/snapshot.c index 8dbb498..c578f18 100644 --- a/src/snapshot.c +++ b/src/snapshot.c @@ -314,34 +314,36 @@ bool term_snapshot_update(struct term_snapshot *s, struct term *t) const struct term_view *term_snapshot_view(const struct term_snapshot *s) { - return &s->view; + return s ? &s->view : NULL; } const struct term_cell *term_snapshot_row(const struct term_snapshot *s, int y) { - if (y < 0 || y >= s->view.size.y) + if (!s || y < 0 || y >= s->view.size.y) return NULL; return s->cells + (size_t)y * s->view.size.x; } uint64_t term_snapshot_row_key(const struct term_snapshot *s, int y) { - if (y < 0 || y >= s->view.size.y) + if (!s || y < 0 || y >= s->view.size.y) return 0; return s->keys[y]; } struct term_span term_snapshot_row_selection(const struct term_snapshot *s, int y) { - if (y < 0 || y >= s->view.size.y) + if (!s || y < 0 || y >= s->view.size.y) return (struct term_span){ 0 }; return s->selection[y]; } int term_snapshot_cluster(const struct term_snapshot *s, uint32_t text, uint32_t *cps, int cap) { + if (!s) + return 0; if (!(text & TERM_TEXT_CLUSTER)) { - if (cap > 0) + if (cps && cap > 0) cps[0] = text; return 1; } @@ -350,7 +352,7 @@ int term_snapshot_cluster(const struct term_snapshot *s, uint32_t text, uint32_t return 0; int n = (int)s->arena[off]; int copy = n < cap ? n : cap; - if (copy > 0) + if (cps && copy > 0) memcpy(cps, &s->arena[off + 1], (size_t)copy * sizeof(*cps)); return n; } @@ -8,6 +8,11 @@ const char *term_unicode_version(void) return UNICODE_DATA_VERSION; } +unsigned term_version(void) +{ + return TERM_VERSION_CODE; +} + void term_lock(struct term *t) { term_write_begin(t); @@ -190,10 +190,11 @@ static inline bool try_text_run(struct term *t, const char *buf, size_t len, return wrote; } +/* The feed flags this build knows. term_feed() rejects any other bit. */ +#define TERM_FEED_KNOWN TERM_FEED_ONLCR + static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigned flags) { - if (!t || !buf || len == 0) - return; t->transport_newline = (flags & TERM_FEED_ONLCR) != 0; uint16_t cur_flags = term_current_flags(t); @@ -366,13 +367,16 @@ static void term_feed_inner(struct term *t, const char *buf, size_t len, unsigne } } -void term_feed(struct term *t, const char *buf, size_t len, unsigned flags) +bool term_feed(struct term *t, const char *buf, size_t len, unsigned flags) { - if (!t || !buf || len == 0) - return; + if (!t || (!buf && len > 0) || (flags & ~TERM_FEED_KNOWN)) + return false; + if (len == 0) + return true; term_write_begin(t); term_feed_inner(t, buf, len, flags); term_write_end(t); + return true; } void term_text_repeat(struct term *t, int count) |
