summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-06-07 12:13:59 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-06-07 12:13:59 +0800
commit6d2c21c4eb53964be68892a738e103c85421cf89 (patch)
tree18cea23db2d13fffdff2a67dd3d4c697d4bceda3
parent0a67db88f03c6d12a6da5e8a61f78e4e56d88672 (diff)
downloadpttbbs-6d2c21c4eb53964be68892a738e103c85421cf89.tar
pttbbs-6d2c21c4eb53964be68892a738e103c85421cf89.tar.gz
pttbbs-6d2c21c4eb53964be68892a738e103c85421cf89.tar.bz2
pttbbs-6d2c21c4eb53964be68892a738e103c85421cf89.tar.lz
pttbbs-6d2c21c4eb53964be68892a738e103c85421cf89.tar.xz
pttbbs-6d2c21c4eb53964be68892a738e103c85421cf89.tar.zst
pttbbs-6d2c21c4eb53964be68892a738e103c85421cf89.zip
DBCS Aware for getdata and edit.
Thanks to Michael Hsin (mhsin) for his patching edit. git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@2781 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--include/modes.h6
-rw-r--r--mbbsd/edit.c105
-rw-r--r--mbbsd/io.c66
-rw-r--r--sample/pttbbs.conf5
4 files changed, 174 insertions, 8 deletions
diff --git a/include/modes.h b/include/modes.h
index 317effac..0ea53e19 100644
--- a/include/modes.h
+++ b/include/modes.h
@@ -148,6 +148,12 @@
#define AUTHOR_NEXT (RS_AUTHOR | RS_FORWARD)
#define AUTHOR_PREV (RS_AUTHOR)
+/* DBCS aware modes */
+enum {
+ DBCS_ASCII,
+ DBCS_LEADING,
+ DBCS_TRAILING,
+} _DBCS_STATUS;
enum {STRIP_ALL = 0, ONLY_COLOR, NO_RELOAD};
diff --git a/mbbsd/edit.c b/mbbsd/edit.c
index 7b828631..dea2ffa7 100644
--- a/mbbsd/edit.c
+++ b/mbbsd/edit.c
@@ -76,7 +76,8 @@ enum {
* ¯S®í²Å¸¹½s¿è
* raw mode:
* ignore Ctrl('S'), Ctrl('Q'), Ctrl('T')
- * ÃÙ¤ê: ³o¦³¤°»ò¥Î?
+ * ÃÙ¤ê: ³o¦³¤°»ò¥Î? ¬Ý°_¨Ó¬O modem ¤W¶Ç¥Î (¨S¤H¦b¥Î³o­Ó¤F§a)
+ * ®³¨Ó·í dbcs option §a
*
* editor ¤ä´©¤F°Ï¶ô¿ï¾Üªº¥\¯à¡]¦h¦æ¿ï¨ú ©Î ³æ¦æ¤¤ªº¤ù¬q¡^¡A¹ï©ó¤@­Ó selected
* block¡A¥i¥H cut, copy, cancel, ©ÎªÌ¦s¨ì¼È¨úÀÉ¡A¬Æ¦Ü¬O©¹¥ª/¥k shift¡C¸Ô¨£
@@ -159,7 +160,6 @@ static editor_internal_t *curr_buf = NULL;
static const char fp_bak[] = "bak";
-
static const char * const BIG5[13] = {
"¡A¡F¡G¡B¡N¡C¡H¡I¡E¡T¡]¡^¡©¡ª¡«¡¬",
"¢b¢c¢d¢e¢f¢g¢h¢i¢j¢k¢l¢m¢n¢o¢pùþ ",
@@ -212,6 +212,42 @@ static const char *table_mode[6] = {
"¢¦"
};
+#ifdef DBCSAWARE_EDIT
+
+static char mbcs_mode =1;
+
+#define IS_BIG5_HI(x) (0x81 <= (x) && (x) <= 0xfe)
+#define IS_BIG5_LOS(x) (0x40 <= (x) && (x) <= 0x7e)
+#define IS_BIG5_LOE(x) (0x80 <= (x) && (x) <= 0xfe)
+#define IS_BIG5_LO(x) (IS_BIG5_LOS(x) || IS_BIG5_LOE(x))
+#define IS_BIG5(hi,lo) (IS_BIG5_HI(hi) && IS_BIG5_LO(lo))
+
+int mchar_len(unsigned char *str)
+{
+ return ((str[0] != '\0' && str[1] != '\0' && IS_BIG5(str[0], str[1])) ?
+ 2 :
+ 1);
+}
+
+#define FC_RIGHT (0)
+#define FC_LEFT (~FC_RIGHT)
+
+int fix_cursor(char *str, int pos, unsigned int dir)
+{
+ int newpos, w;
+
+ for(newpos = 0;
+ *str != '\0' &&
+ (w = mchar_len(str),
+ newpos + 1 + (dir & (w - 1))) <= pos;
+ str += w, newpos += w)
+ ;
+
+ return newpos;
+}
+
+#endif
+
/* °O¾ÐÅéºÞ²z»P½s¿è³B²z */
static void
@@ -1846,6 +1882,28 @@ display_textline_internal(textline_t *p, int i, int min, int max)
outs("\033[m");
(*output)(p->data + max);
} else
+
+#ifdef DBCSAWARE_EDIT
+ if(mbcs_mode && curr_buf->edit_margin > 0)
+ {
+ if(curr_buf->edit_margin >= p->len)
+ {
+ (*output)("");
+ } else {
+ int newpnt = curr_buf->edit_margin;
+ unsigned char *pdata = &p->data[0] + curr_buf->edit_margin;
+ if(mbcs_mode)
+ newpnt = fix_cursor(p->data, newpnt, FC_LEFT);
+ if(newpnt == curr_buf->edit_margin-1)
+ {
+ (*output)(" ");
+ pdata++;
+ }
+ (*output)(pdata);
+ }
+
+ } else
+#endif
(*output)((curr_buf->edit_margin < p->len) ? &p->data[curr_buf->edit_margin] : "");
if (inblock)
@@ -2652,6 +2710,10 @@ vedit(char *fpath, int saveheader, int *islocal)
curr_buf->oldcurrline = curr_buf->currline;
break;
case 'R':
+#ifdef DBCSAWARE_EDIT
+ case 'r':
+ mbcs_mode =! mbcs_mode;
+#endif
curr_buf->raw_mode ^= 1;
break;
case 'I':
@@ -2767,6 +2829,10 @@ vedit(char *fpath, int saveheader, int *islocal)
if (curr_buf->ansimode)
curr_buf->currpnt = n2ansi(curr_buf->currpnt, curr_buf->currline);
curr_buf->currpnt--;
+#ifdef DBCSAWARE_EDIT
+ if(mbcs_mode)
+ curr_buf->currpnt = fix_cursor(curr_buf->currline->data, curr_buf->currpnt, FC_LEFT);
+#endif
if (curr_buf->ansimode)
curr_buf->currpnt = ansi2n(curr_buf->currpnt, curr_buf->currline);
} else if (curr_buf->currline->prev) {
@@ -2781,6 +2847,10 @@ vedit(char *fpath, int saveheader, int *islocal)
if (curr_buf->ansimode)
curr_buf->currpnt = n2ansi(curr_buf->currpnt, curr_buf->currline);
curr_buf->currpnt++;
+#ifdef DBCSAWARE_EDIT
+ if(mbcs_mode)
+ curr_buf->currpnt = fix_cursor(curr_buf->currline->data, curr_buf->currpnt, FC_RIGHT);
+#endif
if (curr_buf->ansimode)
curr_buf->currpnt = ansi2n(curr_buf->currpnt, curr_buf->currline);
} else if (curr_buf->currline->next) {
@@ -2898,8 +2968,23 @@ vedit(char *fpath, int saveheader, int *islocal)
}
break;
}
+#ifndef DBCSAWARE_EDIT
curr_buf->currpnt--;
delete_char();
+#else
+ {
+ int newpnt = curr_buf->currpnt - 1;
+
+ if(mbcs_mode)
+ newpnt = fix_cursor(curr_buf->currline->data, newpnt, FC_LEFT);
+
+ for(; curr_buf->currpnt > newpnt;)
+ {
+ curr_buf->currpnt --;
+ delete_char();
+ }
+ }
+#endif
}
break;
case Ctrl('D'):
@@ -2916,7 +3001,19 @@ vedit(char *fpath, int saveheader, int *islocal)
}
curr_buf->redraw_everything = YEA;
} else {
+#ifndef DBCSAWARE_EDIT
delete_char();
+#else
+ {
+ int w = 1;
+
+ if(mbcs_mode)
+ w = mchar_len(curr_buf->currline->data + curr_buf->currpnt);
+
+ for(; w > 0; w --)
+ delete_char();
+ }
+#endif
if (curr_buf->ansimode)
curr_buf->currpnt = ansi2n(n2ansi(curr_buf->currpnt, curr_buf->currline), curr_buf->currline);
}
@@ -2971,6 +3068,10 @@ vedit(char *fpath, int saveheader, int *islocal)
window_scroll_down();
else if (cursor_at_bottom_line())
window_scroll_up();
+#ifdef DBCSAWARE_EDIT
+ if(mbcs_mode)
+ curr_buf->currpnt = fix_cursor(curr_buf->currline->data, curr_buf->currpnt, FC_LEFT);
+#endif
}
if (curr_buf->ansimode)
diff --git a/mbbsd/io.c b/mbbsd/io.c
index 35130710..0b9a7f53 100644
--- a/mbbsd/io.c
+++ b/mbbsd/io.c
@@ -529,6 +529,32 @@ strip_nonebig5(unsigned char *str, int maxlen)
str[len]='\0';
}
+#ifdef DBCSAWARE_GETDATA
+
+int getDBCSstatus(unsigned char *s, int pos)
+{
+ int sts = DBCS_ASCII;
+ while(pos >= 0)
+ {
+ if(sts == DBCS_LEADING)
+ sts = DBCS_TRAILING;
+ else if (*s >= 0x80)
+ {
+ sts = DBCS_LEADING;
+ } else {
+ sts = DBCS_ASCII;
+ }
+ s++, pos--;
+ }
+ return sts;
+}
+
+#else
+
+#define dbcs_off (1)
+
+#endif
+
int
oldgetdata(int line, int col, const char *prompt, char *buf, int len, int echo)
{
@@ -604,22 +630,42 @@ oldgetdata(int line, int col, const char *prompt, char *buf, int len, int echo)
clen = currchar = strlen(buf);
break;
case KEY_LEFT:
- if (currchar)
+ if (currchar > 0)
+ {
--currchar;
+#ifdef DBCSAWARE_GETDATA
+ if(currchar > 0 &&
+ getDBCSstatus(buf, currchar) == DBCS_TRAILING)
+ currchar --;
+#endif
+ }
break;
case KEY_RIGHT:
if (buf[currchar])
+ {
++currchar;
+#ifdef DBCSAWARE_GETDATA
+ if(buf[currchar] &&
+ getDBCSstatus(buf, currchar) == DBCS_TRAILING)
+ currchar++;
+#endif
+ }
break;
case '\177':
case Ctrl('H'):
if (currchar) {
- currchar--;
- clen--;
+#ifdef DBCSAWARE_GETDATA
+ int dbcs_off = (getDBCSstatus(buf, currchar-1) == DBCS_TRAILING) ? 2 : 1;
+#endif
+ currchar -= dbcs_off;
+ clen -= dbcs_off;
for (i = currchar; i <= clen; i++)
- buf[i] = buf[i + 1];
+ buf[i] = buf[i + dbcs_off];
move(y, x + clen);
outc(' ');
+#ifdef DBCSAWARE_GETDATA
+ if(dbcs_off > 1) outc(' ');
+#endif
move(y, x);
edit_outs(buf);
}
@@ -627,6 +673,7 @@ oldgetdata(int line, int col, const char *prompt, char *buf, int len, int echo)
case Ctrl('Y'):
currchar = 0;
case Ctrl('K'):
+ /* we shoud be able to avoid DBCS issues in ^K mode */
buf[currchar] = '\0';
move(y, x + currchar);
for (i = currchar; i < clen; i++)
@@ -636,11 +683,18 @@ oldgetdata(int line, int col, const char *prompt, char *buf, int len, int echo)
case Ctrl('D'):
case KEY_DEL:
if (buf[currchar]) {
- clen--;
+#ifdef DBCSAWARE_GETDATA
+ int dbcs_off = (buf[currchar+1] &&
+ getDBCSstatus(buf, currchar+1) == DBCS_TRAILING) ? 2 : 1;
+#endif
+ clen -= dbcs_off;
for (i = currchar; i <= clen; i++)
- buf[i] = buf[i + 1];
+ buf[i] = buf[i + dbcs_off];
move(y, x + clen);
outc(' ');
+#ifdef DBCSAWARE_GETDATA
+ if(dbcs_off > 1) outc(' ');
+#endif
move(y, x);
edit_outs(buf);
}
diff --git a/sample/pttbbs.conf b/sample/pttbbs.conf
index dabecad3..8e5cb552 100644
--- a/sample/pttbbs.conf
+++ b/sample/pttbbs.conf
@@ -118,6 +118,11 @@
/* ­Y©w¸q, ¦b¨Ï¥ÎªÌµù¥U¤§«e, ·|¥ýÅã¥Ü¥X¸ÓÀÉ®×, ¸g¨Ï¥ÎªÌ½T»{«á¤~¯àµù¥U */
//#define HAVE_USERAGREEMENT "etc/UserAgreement"
+/* DBCS Aware: Åý´å¼Ð¤£·|¶]¨ì DBCS trailing bytes ¤W
+ * ¦ýª`·N³o·|¦Y¤£¤Ö CPU */
+//#define DBCSAWARE_GETDATA
+//#define DBCSAWARE_EDIT
+
/* ¨Ï¥Î·s¦¡ªº pmore (piaip's more) ¥N´À¦¡ bug §ì¤£§¹ªº more */
#define USE_PIAIP_MORE