[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