aboutsummaryrefslogtreecommitdiff
path: root/src/console.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/console.c')
-rw-r--r--src/console.c78
1 files changed, 50 insertions, 28 deletions
diff --git a/src/console.c b/src/console.c
index 073274f..7286288 100644
--- a/src/console.c
+++ b/src/console.c
@@ -6,8 +6,7 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
-#include <unicode/utext.h>
-#include <unicode/ubrk.h>
+#include <grapheme.h>
struct imv_console {
char *buffer;
@@ -22,25 +21,57 @@ struct imv_console {
char *history_before; /* contents of line before history was opened */
};
-/* Iterates forwards over characters in a UTF-8 string */
-static size_t next_char(char *buffer, size_t position)
+static size_t grapheme_strlen(char *str)
{
- size_t result = position;
- UErrorCode status = U_ZERO_ERROR;
- UText *ut = utext_openUTF8(NULL, buffer, -1, &status);
+ size_t len = 0, ret = 0;
+ char *s = strdup(str);
+ while (*s != '\0') {
+ len = grapheme_bytelen(s);
+ ret += len;
+ s += len;
+ }
+ return ret;
+}
- UBreakIterator *it = ubrk_open(UBRK_CHARACTER, NULL, NULL, 0, &status);
- ubrk_setUText(it, ut, &status);
+static int32_t grapheme_following(char* str, size_t strlength, int32_t offset)
+{
+ int32_t result;
+ char *s = strdup(str);
+ s += offset;
+ if (!((int)offset<(int)strlength)||*s=='\0')
+ return -1;
+ result = (int32_t) grapheme_bytelen(s);
+ return ((result + offset) > strlength) ? -2 : result + offset;
+}
- int boundary = ubrk_following(it, (int)position);
- if (boundary != UBRK_DONE) {
- result = (size_t)boundary;
+static int32_t grapheme_preceding(char *str, size_t strlength, int32_t offset)
+{
+ size_t len;
+ int32_t result = 0;
+ if (offset<=0)
+ return -1;
+ char *s = strdup(str);
+ while (*s != '\0' && result < strlength) {
+ len = grapheme_bytelen(s);
+ s += len;
+ if ((result + (int32_t)len) < offset)
+ result += (int32_t)len;
+ else
+ return result;
}
+ return -2;
+}
- ubrk_close(it);
+/* Iterates forwards over characters in a UTF-8 string */
+static size_t next_char(char *buffer, size_t position)
+{
+ size_t result = position;
+ size_t length = grapheme_strlen(buffer);
+ int boundary = grapheme_following(buffer, length, position);
+ if (!(boundary < 0))
+ result = (size_t)boundary;
- utext_close(ut);
- assert(U_SUCCESS(status));
+ assert(boundary != -2);
return result;
}
@@ -48,21 +79,12 @@ static size_t next_char(char *buffer, size_t position)
static size_t prev_char(char *buffer, size_t position)
{
size_t result = position;
- UErrorCode status = U_ZERO_ERROR;
- UText *ut = utext_openUTF8(NULL, buffer, -1, &status);
-
- UBreakIterator *it = ubrk_open(UBRK_CHARACTER, NULL, NULL, 0, &status);
- ubrk_setUText(it, ut, &status);
-
- int boundary = ubrk_preceding(it, (int)position);
- if (boundary != UBRK_DONE) {
+ size_t length = grapheme_strlen(buffer);
+ int boundary = grapheme_preceding(buffer, length, position);
+ if (!(boundary < 0))
result = (size_t)boundary;
- }
-
- ubrk_close(it);
- utext_close(ut);
- assert(U_SUCCESS(status));
+ assert(boundary != -2);
return result;
}