aboutsummaryrefslogtreecommitdiff
path: root/text-util.c
diff options
context:
space:
mode:
authorMarc André Tanner <mat@brain-dump.org>2015-11-23 10:48:41 +0100
committerMarc André Tanner <mat@brain-dump.org>2015-11-23 14:18:27 +0100
commitc1584693cbb2d9ea2f2cfb4fc528da30b2554a91 (patch)
tree0cadc0bccd9ac91d9118c0e061e2566c7054e70b /text-util.c
parent0613073092b9f4172b5b87e9c7f243ff6d61f723 (diff)
downloadvis-c1584693cbb2d9ea2f2cfb4fc528da30b2554a91.tar.gz
vis-c1584693cbb2d9ea2f2cfb4fc528da30b2554a91.tar.xz
vis: improve replacement of combining characters
Diffstat (limited to 'text-util.c')
-rw-r--r--text-util.c29
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;
+}