[uim-commit] r1148 - trunk/fep
yamamoto at freedesktop.org
yamamoto at freedesktop.org
Sun Aug 7 16:02:10 EST 2005
Author: yamamoto
Date: 2005-08-06 23:02:03 -0700 (Sat, 06 Aug 2005)
New Revision: 1148
Modified:
trunk/fep/escseq.c
Log:
* fep/escseq.c (get_cursor_position) :
parse cursor report by own routine instead of sscanf
Modified: trunk/fep/escseq.c
===================================================================
--- trunk/fep/escseq.c 2005-08-06 22:47:20 UTC (rev 1147)
+++ trunk/fep/escseq.c 2005-08-07 06:02:03 UTC (rev 1148)
@@ -503,6 +503,12 @@
}
}
+#define range_check(i) do { \
+ if ((i) > escseq_len - 1) { \
+ goto retry; \
+ } \
+} while(FALSE)
+
/*
* ¸½ºß¤Î¥«¡¼¥½¥ë°ÌÃÖ¤òÊÖ¤¹
* º¸¾å¤Ï0, 0
@@ -510,7 +516,7 @@
*/
struct point_tag get_cursor_position(void)
{
- char ibuf[BUFSIZ];
+ char ibuf[300];
ssize_t len = 0;
ssize_t read_len = 0;
char *escseq = ibuf - 1;
@@ -526,6 +532,7 @@
while (TRUE) {
char *next_escseq;
+ retry:
len += (read_len = read_stdin(ibuf + len, sizeof(ibuf) - len));
if (read_len == 0) {
debug(("loop = %d\n", loop_count + 1));
@@ -533,7 +540,6 @@
break;
}
}
- ibuf[len] = '\0';
debug2(("get = \""));
debug_write2(ibuf, len);
@@ -542,37 +548,126 @@
if (escseq != ibuf - 1) {
escseq--;
}
+
+ /* NUL¤¬Æþ¤Ã¤Æ¤¤¤ë¤«¤â¤·¤ì¤Ê¤¤¤Î¤Ç strchr ¤Ç¤Ï¤Ê¤¯ memchr */
while ((next_escseq = memchr(escseq + 1, ESCAPE_CODE, len - (escseq - ibuf) - 1)) != NULL) {
- int n;
- char R;
+ int i = 1;
+ int row = UNDEFINED;
+ int col = UNDEFINED;
+ char unget_buf[300];
+ int unget_count = 0;
+ int escseq_len;
+
escseq = next_escseq;
- n = sscanf(escseq, "\033[%d;%d%c", &(s_cursor.row), &(s_cursor.col), &R);
- if (n == 3 && R == 'R') {
- char *next_to_R = strchr(escseq, 'R') + 1;
- /* ¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤ÎÁ°¤Ëʸ»úÎ󤬤¢¤ë¤« */
- if (escseq > ibuf) {
- unget_stdin(ibuf, escseq - ibuf);
+ escseq_len = len - (escseq - ibuf);
+
+ if (strlen("\033[0;0R") > escseq_len) {
+ break; /* goto retry */
+ }
+
+ /* n = sscanf(escseq, "\033[%d;%d%c", &(s_cursor.row), &(s_cursor.col), &R); */
+
+ if (escseq[i] != '[') {
+ unget_buf[unget_count++] = escseq[i++];
+ if (escseq[i] != '[') {
+ break; /* goto retry */
}
+ }
+
+ if (escseq[i + 1] == '[') {
+ unget_buf[unget_count++] = escseq[i++];
+ }
- /* ¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤Î¸å¤Îʸ»úÎó */
- unget_stdin(next_to_R, len - (next_to_R - ibuf));
+ while (TRUE) {
+ i++;
+ range_check(i);
+ if (!isdigit((unsigned char)escseq[i])) {
+ if (row != UNDEFINED && escseq[i] == ';') {
+ break;
+ }
+ unget_buf[unget_count++] = escseq[i++];
+ range_check(i);
+ }
+ if (isdigit((unsigned char)escseq[i])) {
+ if (row == UNDEFINED) {
+ row = 0;
+ }
+ row = row * 10 + escseq[i] - '0';
+ } else {
+ break;
+ }
+ }
- s_cursor.row--;
- s_cursor.col--;
- s_cursor.row -= s_cursor_diff.row;
- s_cursor.col -= s_cursor_diff.col;
+ if (row == UNDEFINED) {
+ break; /* goto retry */
+ }
- /* GNU screen ¤Ç¤Ï¤³¤¦¤Ê¤ë¤³¤È¤¬¤¢¤ë */
- if (s_cursor.col > g_win->ws_col - 1) {
- put_crlf();
+ if (escseq[i] != ';') {
+ break; /* goto retry */
+ }
+
+ range_check(i + 1);
+ if (escseq[i + 1] == ';') {
+ unget_buf[unget_count++] = escseq[i++];
+ }
+
+ while (TRUE) {
+ i++;
+ range_check(i);
+ if (!isdigit((unsigned char)escseq[i])) {
+ if (col != UNDEFINED && escseq[i] == 'R') {
+ break;
+ }
+ unget_buf[unget_count++] = escseq[i++];
+ range_check(i);
}
- debug(("<get row = %d col = %d>", s_cursor.row, s_cursor.col));
- return s_cursor;
+ if (isdigit((unsigned char)escseq[i])) {
+ if (col == UNDEFINED) {
+ col = 0;
+ }
+ col = col * 10 + escseq[i] - '0';
+ } else {
+ break;
+ }
+ }
- } else {
- /* ESC¤Ï¤¢¤ë¤¬, ¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤È¤·¤Æ¤ÏÉÔ½½Ê¬ */
- s_cursor.row = s_cursor.col = UNDEFINED;
+ if (col == UNDEFINED) {
+ break; /* goto retry */
}
+
+ if (escseq[i] != 'R') {
+ break; /* goto retry */
+ }
+
+ /* ¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤ÎÁ°¤Ëʸ»úÎ󤬤¢¤ë¤« */
+ if (escseq > ibuf) {
+ unget_stdin(ibuf, escseq - ibuf);
+ }
+
+ /* ¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤ÎÃæ¤Îʸ»úÎó */
+ if (unget_count > 0) {
+ unget_stdin(unget_buf, unget_count);
+ }
+
+ /* ¥¨¥¹¥±¡¼¥×¥·¡¼¥±¥ó¥¹¤Î¸å¤Îʸ»úÎó */
+ if (i < escseq_len - 1) {
+ unget_stdin(&escseq[i + 1], escseq_len - 1 - i);
+ }
+
+ row--;
+ col--;
+ row -= s_cursor_diff.row;
+ col -= s_cursor_diff.col;
+
+ s_cursor.row = row;
+ s_cursor.col = col;
+
+ /* GNU screen ¤Ç¤Ï¤³¤¦¤Ê¤ë¤³¤È¤¬¤¢¤ë */
+ if (s_cursor.col > g_win->ws_col - 1) {
+ put_crlf();
+ }
+ debug(("<get row = %d col = %d>", s_cursor.row, s_cursor.col));
+ return s_cursor;
}
}
More information about the uim-commit
mailing list