diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2015-11-23 10:48:41 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2015-11-23 14:18:27 +0100 |
| commit | c1584693cbb2d9ea2f2cfb4fc528da30b2554a91 (patch) | |
| tree | 0cadc0bccd9ac91d9118c0e061e2566c7054e70b /text-util.c | |
| parent | 0613073092b9f4172b5b87e9c7f243ff6d61f723 (diff) | |
| download | vis-c1584693cbb2d9ea2f2cfb4fc528da30b2554a91.tar.gz vis-c1584693cbb2d9ea2f2cfb4fc528da30b2554a91.tar.xz | |
vis: improve replacement of combining characters
Diffstat (limited to 'text-util.c')
| -rw-r--r-- | text-util.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/text-util.c b/text-util.c index 2b48719..4d3406b 100644 --- a/text-util.c +++ b/text-util.c @@ -1,5 +1,7 @@ #include "text-util.h" #include "util.h" +#include <wchar.h> +#include <errno.h> bool text_range_valid(Filerange *r) { return r->start != EPOS && r->end != EPOS && r->start <= r->end; @@ -46,3 +48,30 @@ bool text_range_overlap(Filerange *r1, Filerange *r2) { bool text_range_contains(Filerange *r, size_t pos) { return text_range_valid(r) && r->start <= pos && pos <= r->end; } + +int text_char_count(const char *data, size_t len) { + int count = 0; + mbstate_t ps = { 0 }; + while (len > 0) { + wchar_t wc; + size_t wclen = mbrtowc(&wc, data, len, &ps); + if (wclen == (size_t)-1 && errno == EILSEQ) { + count++; + while (!ISUTF8(*data)) + data++, len--; + } else if (wclen == (size_t)-2) { + break; + } else if (wclen == 0) { + count++; + data++; + len--; + } else { + int width = wcwidth(wc); + if (width != 0) + count++; + data += wclen; + len -= wclen; + } + } + return count; +} |
