#include "rlwrap.h" #include /* rlwrap was written without worrying about multibyte characters. the functions below "retrofit" multi-byte support by providing functions that can be used with minimal adaptations in the usual idioms like for (char *p = s; *p; p++) which can be re-written as: for(mbc_initstate(&st), p = s; *p; mbc_inc(&p, &st)) { c.f. https://kirste.userpage.fu-berlin.de/chemnet/use/info/libc/libc_18.html */ /* voor ascii chars is next_mbc(p) == p+1, maar voor een multibyte positie kan het ook bijv. p+3 of meer zijn */ #ifdef MULTIBYTE_AWARE MBSTATE * mbc_initstate(MBSTATE *st) { memset (st, 0, sizeof(MBSTATE)); return st; } MBSTATE * mbc_copystate(MBSTATE st, MBSTATE *stc) { *stc = st; return stc; } int mbc_is_valid(const char *mb_string, const MBSTATE *st) { MBSTATE scrap = *st; return (int) mbrlen(mb_string, MB_LEN_MAX, &scrap ) >= 0; } const char * mbc_next(const char *mb_string, MBSTATE *st) { if (!*mb_string || !mbc_is_valid(mb_string, st)) return mb_string + 1; else return mb_string + mbrlen(mb_string, MB_LEN_MAX, st); } const char * mbc_inc(const char **mbc, MBSTATE *st) { return (*mbc = mbc_next(*mbc, st)); } char * mbc_first(const char *mb_string, const MBSTATE *st) { MBSTATE scrap = *st; char buffer[MB_LEN_MAX+1]; int len = mbrlen(mb_string, MB_LEN_MAX, &scrap ); strncpy(buffer, mb_string, len); buffer[len] = '\0'; return mysavestring(buffer); } int mbc_charwidth(const char *p, MBSTATE *st) { int width = mbrlen(p, MB_LEN_MAX, st); if (width < 0) { DPRINTF1(DEBUG_READLINE, "invalid multi-byte charavter at stert of %s", M(p)); width = 1; /* if we don''n recognise it, interpret it as a byte */ } return width; } /* copy the first (wide) character in p to *q, incrementing q to one past the result. Does not NULL-terminate the copy */ void mbc_copy(const char *p, char **q, MBSTATE *st) { int i; for(i=0; i < mbc_charwidth(p, st); i++) *(*q)++ = p[i]; } int is_multibyte(const char *mb_char, const MBSTATE *st) { MBSTATE scrap = *st; return mbc_is_valid(mb_char, st) && mbrlen(mb_char, MB_LEN_MAX, &scrap) > 1; } size_t mbc_strnlen(const char *mb_string, size_t maxlen, MBSTATE *st) { size_t len; const char *p; for (len = 0, p = mb_string; *p && p < mb_string + maxlen; mbc_inc(&p, st)) len++; return len; } #else /* if not MULTIBYTE_AWARE: */ MBSTATE * mbc_initstate(MBSTATE *st) { return st; } MBSTATE * mbc_copystate(MBSTATE st, MBSTATE *stc) { *stc = st; return stc; } int mbc_is_valid(const char *UNUSED(string), const MBSTATE *UNUSED(st)) { return TRUE; } const char * mbc_next(const char *string, MBSTATE *UNUSED(st)) { return string + 1; } const char * mbc_inc(const char **p, MBSTATE *UNUSED(st)) { return (*p)++; } char * mbc_first(const char *string, const MBSTATE *UNUSED(st)) { char p[2] = " "; p[0] = string[0]; return mysavestring(p); } int mbc_charwidth(const char *UNUSED(p), MBSTATE *UNUSED(st)) { return 1; } /* copy the first byte in p to *q, incrementing q */ void mbc_copy(const char *p, char **q, MBSTATE *UNUSED(st)) { *(*q)++ = *p; } int is_multibyte(const char *UNUSED(p), const MBSTATE *UNUSED(st)) { return FALSE; } size_t mbc_strnlen(const char *string, size_t maxlen, MBSTATE *UNUSED(st)) { return strnlen(string, maxlen); } #endif