mirror of
https://github.com/tmux/tmux.git
synced 2025-09-02 21:56:57 +00:00
Merge branch 'obsd-master'
Conflicts: Makefile tmux.1 window.c
This commit is contained in:
122
utf8.c
122
utf8.c
@ -18,6 +18,7 @@
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
@ -200,6 +201,16 @@ int utf8_overlap(struct utf8_width_entry *, struct utf8_width_entry *);
|
||||
u_int utf8_combine(const struct utf8_data *);
|
||||
u_int utf8_width(const struct utf8_data *);
|
||||
|
||||
/* Set a single character. */
|
||||
void
|
||||
utf8_set(struct utf8_data *utf8data, u_char ch)
|
||||
{
|
||||
*utf8data->data = ch;
|
||||
utf8data->size = 1;
|
||||
|
||||
utf8data->width = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open UTF-8 sequence.
|
||||
*
|
||||
@ -248,8 +259,7 @@ utf8_append(struct utf8_data *utf8data, u_char ch)
|
||||
|
||||
/* Check if two width tree entries overlap. */
|
||||
int
|
||||
utf8_overlap(
|
||||
struct utf8_width_entry *item1, struct utf8_width_entry *item2)
|
||||
utf8_overlap(struct utf8_width_entry *item1, struct utf8_width_entry *item2)
|
||||
{
|
||||
if (item1->first >= item2->first && item1->first <= item2->last)
|
||||
return (1);
|
||||
@ -394,3 +404,111 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
|
||||
*dst = '\0';
|
||||
return (dst - start);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string into a buffer of UTF-8 characters. Terminated by size == 0.
|
||||
* Caller frees.
|
||||
*/
|
||||
struct utf8_data *
|
||||
utf8_fromcstr(const char *src)
|
||||
{
|
||||
struct utf8_data *dst;
|
||||
size_t n;
|
||||
int more;
|
||||
|
||||
dst = NULL;
|
||||
|
||||
n = 0;
|
||||
while (*src != '\0') {
|
||||
dst = xrealloc(dst, n + 1, sizeof *dst);
|
||||
if (utf8_open(&dst[n], *src)) {
|
||||
more = 1;
|
||||
while (*++src != '\0' && more)
|
||||
more = utf8_append(&dst[n], *src);
|
||||
if (!more) {
|
||||
n++;
|
||||
continue;
|
||||
}
|
||||
src -= dst[n].have;
|
||||
}
|
||||
utf8_set(&dst[n], *src);
|
||||
src++;
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
dst = xrealloc(dst, n + 1, sizeof *dst);
|
||||
dst[n].size = 0;
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* Convert from a buffer of UTF-8 characters into a string. Caller frees. */
|
||||
char *
|
||||
utf8_tocstr(struct utf8_data *src)
|
||||
{
|
||||
char *dst;
|
||||
size_t n;
|
||||
|
||||
dst = NULL;
|
||||
|
||||
n = 0;
|
||||
for(; src->size != 0; src++) {
|
||||
dst = xrealloc(dst, n + src->size, 1);
|
||||
memcpy(dst + n, src->data, src->size);
|
||||
n += src->size;
|
||||
}
|
||||
|
||||
dst = xrealloc(dst, n + 1, 1);
|
||||
dst[n] = '\0';
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* Get width of UTF-8 string. */
|
||||
u_int
|
||||
utf8_cstrwidth(const char *s)
|
||||
{
|
||||
struct utf8_data tmp;
|
||||
u_int width;
|
||||
int more;
|
||||
|
||||
width = 0;
|
||||
while (*s != '\0') {
|
||||
if (utf8_open(&tmp, *s)) {
|
||||
more = 1;
|
||||
while (*++s != '\0' && more)
|
||||
more = utf8_append(&tmp, *s);
|
||||
if (!more) {
|
||||
width += tmp.width;
|
||||
continue;
|
||||
}
|
||||
s -= tmp.have;
|
||||
}
|
||||
width++;
|
||||
s++;
|
||||
}
|
||||
return (width);
|
||||
}
|
||||
|
||||
/* Trim UTF-8 string to width. Caller frees. */
|
||||
char *
|
||||
utf8_trimcstr(const char *s, u_int width)
|
||||
{
|
||||
struct utf8_data *tmp, *next;
|
||||
char *out;
|
||||
u_int at;
|
||||
|
||||
tmp = utf8_fromcstr(s);
|
||||
|
||||
at = 0;
|
||||
for (next = tmp; next->size != 0; next++) {
|
||||
if (at + next->width > width) {
|
||||
next->size = 0;
|
||||
break;
|
||||
}
|
||||
at += next->width;
|
||||
}
|
||||
|
||||
out = utf8_tocstr(tmp);
|
||||
free(tmp);
|
||||
return (out);
|
||||
}
|
||||
|
Reference in New Issue
Block a user