From 81aedaf08d5fb34eddb2cf838a434aed1bfe3a6f Mon Sep 17 00:00:00 2001 From: piaip Date: Sun, 16 Dec 2007 04:43:32 +0000 Subject: - disable interupting ANSI inside DBCS characters (for UTF-8 or non-DBCS clients) git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3688 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- include/libbbsutil.h | 1 + include/uflags.h | 10 ++++++-- mbbsd/screen.c | 28 +++++++++++++++++++++-- mbbsd/user.c | 2 ++ src/libbbsutil/string.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 4 deletions(-) diff --git a/include/libbbsutil.h b/include/libbbsutil.h index 5b877f52..f2e31a53 100644 --- a/include/libbbsutil.h +++ b/include/libbbsutil.h @@ -63,6 +63,7 @@ extern int strip_blank(char *cbuf, char *buf); extern int strip_ansi(char *buf, const char *str, enum STRIP_FLAG flag); extern int strlen_noansi(const char *s); extern void strip_nonebig5(unsigned char *str, int maxlen); +extern int DBCS_RemoveIntrEscape(unsigned char *buf, int *len); extern int invalid_pname(const char *str); extern int is_number(const char *p); extern unsigned StringHash(const char *s); diff --git a/include/uflags.h b/include/uflags.h index 752dc73a..ea27bee5 100644 --- a/include/uflags.h +++ b/include/uflags.h @@ -4,6 +4,12 @@ #ifndef INCLUDE_UFLAGS_H #define INCLUDE_UFLAGS_H +// TODO in order to prevent masking with wrong variables +// (since we have 2 flags), it is better to rename the +// masks with their flag index, eg: +// UF_PAGER, +// UF2_WATER_ORIG, + /* -------------------- userec_t.uflag (unsigned int) */ /* UNKNOWN */ @@ -21,9 +27,9 @@ //#define MIND_FLAG 0x00000100 /* true if mind search mode open <-Heat*/ /* DBCS CONFIG */ +/* please keep these even if you don't have DBCSAWARE features turned on */ #define DBCSAWARE_FLAG 0x00000200 /* true if DBCS-aware enabled. */ -/* please keep this even if you don't have DBCSAWARE features turned on */ -// #define DBCS__??? 0x00000400 +#define DBCS_NOINTRESC 0x00000400 /* no Escapes interupting DBCS characters */ // #define DBCS__??? 0x00000800 /* Modification Mark (~) */ diff --git a/mbbsd/screen.c b/mbbsd/screen.c index 8256ba5e..59e0addb 100644 --- a/mbbsd/screen.c +++ b/mbbsd/screen.c @@ -121,7 +121,8 @@ void redoscr(void) { register screenline_t *bp; - register int i, j, len; + register int i, j; + int len; o_clear(); for (tc_col = tc_line = i = 0, j = roll; i < scr_lns; i++, j++) { @@ -130,6 +131,17 @@ redoscr(void) bp = &big_picture[j]; if ((len = bp->len)) { rel_move(tc_col, tc_line, 0, i); + +#ifdef DBCSAWARE + if (!(bp->mode & STANDOUT) && + (cuser.uflag & DBCS_NOINTRESC) && + DBCS_RemoveIntrEscape(bp->data, &len)) + { + // if anything changed, dirty whole line. + bp->len = len; + } +#endif // DBCSAWARE + if (bp->mode & STANDOUT) { standoutput((char *)bp->data, 0, len, bp->sso, bp->eso); } @@ -188,7 +200,8 @@ refresh(void) { /* TODO remove unnecessary refresh() call, to save CPU time */ register screenline_t *bp = big_picture; - register int i, j, len; + register int i, j; + int len; if (num_in_buf()) return; @@ -221,6 +234,17 @@ refresh(void) { bp->mode &= ~(MODIFIED); +#ifdef DBCSAWARE + if (!(bp->mode & STANDOUT) && + (cuser.uflag & DBCS_NOINTRESC) && + DBCS_RemoveIntrEscape(bp->data, &len)) + { + // if anything changed, dirty whole line. + bp->len = len; + bp->smod = 0; bp->emod = len; + } +#endif // DBCSAWARE + // more effort to determine ANSI smod if (bp->smod > 0) { diff --git a/mbbsd/user.c b/mbbsd/user.c index f2475e95..05289ef6 100644 --- a/mbbsd/user.c +++ b/mbbsd/user.c @@ -335,6 +335,7 @@ void Customize(void) COLORED_MODMARK, #ifdef DBCSAWARE DBCSAWARE_FLAG, + DBCS_NOINTRESC, #endif 0, }; @@ -345,6 +346,7 @@ void Customize(void) "改用色彩代替修改符號 (+)", #ifdef DBCSAWARE "自動偵測雙位元字集(如全型中文)", + "禁止插入雙位元的色碼(一字雙色)", #endif 0, }; diff --git a/src/libbbsutil/string.c b/src/libbbsutil/string.c index 695d65ab..b2e7612e 100644 --- a/src/libbbsutil/string.c +++ b/src/libbbsutil/string.c @@ -206,6 +206,67 @@ strip_nonebig5(unsigned char *str, int maxlen) str[len]='\0'; } +int DBCS_RemoveIntrEscape(unsigned char *buf, int *len) +{ + register int isInAnsi = 0, isInDBCS = 0; + int l = 0, i = 0, oldl, iansi = 0; + + if (len) l = *len; else l = strlen((const char*)buf); + oldl = l; + + for (i = 0; i < l; i++) + { + if (buf[i] == ESC_CHR && !isInAnsi) + { + // new escape + isInAnsi = 1; + iansi = i; + continue; + } + + // character + if (isInAnsi) + { + // closing ANSI section? + switch (isInAnsi) + { + case 1: // normal ANSI + if (buf[i] == '[') + isInAnsi = 2; + else + isInAnsi = 0; // unknown command + break; + + case 2: + if (isEscapeParam(buf[i])) + break; + else + isInAnsi = 0; + break; + } + if (isInAnsi == 0 && isInDBCS && i+1 < l) + { + // interupting ANSI closed, let's modify the string + int sz = i + 1 - iansi; // size to move + memmove(buf+iansi, buf+i+1, l-i-1); + l -= sz; + i = iansi-1; // for the ++ in loop + } + } else if (isInDBCS) { + // not ANSI but in DBCS. finished one char. + isInDBCS = 0; + } else if (buf[i] >= 0x80) { + // DBCS lead. + isInDBCS = 1; + } else { + // normal character. + } + } + + if(len) *len = l; + return (oldl != l) ? 1 : 0; +} + /* ----------------------------------------------------- */ /* 字串檢查函數:英文、數字、檔名、E-mail address */ /* ----------------------------------------------------- */ -- cgit v1.2.3