M meson.build => meson.build +10 -1
@@ 38,6 38,15 @@ else
target_single_ws = false
endif
+_unicode = get_option('unicode')
+if _unicode == 'icu'
+ unicode_lib = dependency('icu-io')
+ add_project_arguments('-DIMV_USE_ICU', language: 'c')
+elif _unicode == 'grapheme'
+ unicode_lib = cc.find_library('grapheme')
+ add_project_arguments('-DIMV_USE_GRAPHEME', language: 'c')
+endif
+
gl_dep = dependency('gl', required: false)
if not gl_dep.found()
# libglvnd fallback for pure-wayland systems
@@ 49,7 58,7 @@ deps_for_imv = [
gl_dep,
dependency('threads'),
dependency('xkbcommon'),
- dependency('icu-io'),
+ unicode_lib,
dependency('inih', fallback : ['inih', 'inih_dep']),
m_dep,
]
M meson_options.txt => meson_options.txt +8 -0
@@ 8,6 8,14 @@ option('windows',
description : 'window system to use'
)
+# Unicode backend - default is ICU
+option('unicode',
+ type: 'combo',
+ value: 'icu',
+ choices : ['icu', 'grapheme'],
+ description : 'unicode library to use'
+)
+
option('test',
type : 'feature',
description : 'enable tests'
M src/console.c => src/console.c +28 -0
@@ 6,8 6,15 @@
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+
+#ifdef IMV_USE_ICU
#include <unicode/utext.h>
#include <unicode/ubrk.h>
+#endif
+
+#ifdef IMV_USE_GRAPHEME
+#include <grapheme.h>
+#endif
struct imv_console {
char *buffer;
@@ 25,6 32,7 @@ struct imv_console {
/* Iterates forwards over characters in a UTF-8 string */
static size_t next_char(char *buffer, size_t position)
{
+ #if defined(IMV_USE_ICU)
size_t result = position;
UErrorCode status = U_ZERO_ERROR;
UText *ut = utext_openUTF8(NULL, buffer, -1, &status);
@@ 42,11 50,19 @@ static size_t next_char(char *buffer, size_t position)
utext_close(ut);
assert(U_SUCCESS(status));
return result;
+ #elif defined(IMV_USE_GRAPHEME)
+ if (buffer[position] != 0) {
+ return position + grapheme_bytelen(buffer + position);
+ } else {
+ return position;
+ }
+ #endif
}
/* Iterates backwards over characters in a UTF-8 string */
static size_t prev_char(char *buffer, size_t position)
{
+ #if defined(IMV_USE_ICU)
size_t result = position;
UErrorCode status = U_ZERO_ERROR;
UText *ut = utext_openUTF8(NULL, buffer, -1, &status);
@@ 64,6 80,18 @@ static size_t prev_char(char *buffer, size_t position)
utext_close(ut);
assert(U_SUCCESS(status));
return result;
+
+ #elif defined(IMV_USE_GRAPHEME)
+ size_t result = 0;
+ size_t step;
+ do {
+ step = grapheme_bytelen(buffer + result);
+ if (result + step >= position)
+ break;
+ result += step;
+ } while (step > 0);
+ return result;
+ #endif
}
static void add_to_history(struct list *history, const char *line)