]> git.neil.brown.name Git - edlib.git/commitdiff
lib-utf8: use do_char_byte()
authorNeilBrown <neil@brown.name>
Wed, 19 Jul 2023 10:34:13 +0000 (20:34 +1000)
committerNeilBrown <neil@brown.name>
Fri, 21 Jul 2023 01:02:10 +0000 (11:02 +1000)
Signed-off-by: NeilBrown <neil@brown.name>
DOC/TODO.md
lib-utf8.c

index 4687dac84cffab312a15581e06bea611260495e6..9f9eda63c221a0fcad4c2ac21a0f67393cc76302 100644 (file)
@@ -62,7 +62,7 @@ the file.
       others so it can easily catch view-changed.
 - [X] C config module that reads an ini-style file to set attributes
       based on path
-- [ ] review all doc:char implementations for simplification.
+- [X] review all doc:char implementations for simplification.
 - [ ] make it easy for a make-search command to search backwards
 
 ### Large
@@ -139,7 +139,6 @@ Core features
 - [ ] explicitly guard against infinite loops in consistency checks
 - [ ] skip consistency checks after several with no stop for input.
 - [ ] unwanted docs too easily appear high in recent-list - *Output*
-- [ ] review all doc:char implementations for simplification.
 - [ ] design a way for a keystroke to interrupt a long-running function.
 - [ ] extend Draw:measure protocol to allow constant-width-fonts to
       cannot-scale displays can be detected and measurement optimised for.
@@ -774,6 +773,7 @@ Module features
 
 ### lang-python
 
+- [ ] review python doc:char implementations for simplification.
 - [ ] repeated alarm(10)/alarm(0) calls slow things down
 - [ ] array index should allow two args, second being a mark for
       doc:get-attr etc.
index 2adbef813922357ed4d66415e4eb148b0066d5e4..8c47d85ad7056ce22f638afaf2ae25161d2e7854 100644 (file)
@@ -9,16 +9,17 @@
 #include <unistd.h>
 #include <stdlib.h>
 
+#define DOC_NEXT utf8_next
+#define DOC_PREV utf8_prev
 #include "core.h"
 
 static struct map *utf8_map safe;
 DEF_LOOKUP_CMD(utf8_handle, utf8_map);
 
-static int utf8_step(struct pane *home safe, struct mark *mark safe,
-                    int num, int num2)
+static inline wint_t utf8_next(struct pane *home safe, struct mark *mark safe,
+                              struct doc_ref *r, bool bytes)
 {
-       int dir = num ? 1 : -1;
-       int move = num2;
+       int move = r == &mark->ref;
        struct pane *p = home->parent;
        wint_t ch;
        struct mark *m = mark;
@@ -28,71 +29,72 @@ static int utf8_step(struct pane *home safe, struct mark *mark safe,
        wint_t ret;
 
        if (move)
-               ch = doc_move(p, m, dir);
+               ch = doc_move(p, m, 1);
        else
-               ch = doc_pending(p, m, dir);
+               ch = doc_pending(p, m, 1);
        if (ch == WEOF || (ch & 0x7f) == ch)
-               return CHAR_RET(ch);
+               return ch;
        if (!move) {
                m = mark_dup(m);
-               doc_move(p, m, dir);
+               doc_move(p, m, 1);
        }
-       if (dir > 0) {
-               i = 0;
+       i = 0;
+       buf[i++] = ch;
+       while ((ch = doc_following(p, m)) != WEOF &&
+              (ch & 0xc0) == 0x80 && i < 10) {
                buf[i++] = ch;
-               while ((ch = doc_following(p, m)) != WEOF &&
-                      (ch & 0xc0) == 0x80 && i < 10) {
-                       buf[i++] = ch;
-                       doc_next(p, m);
-               }
-               b = buf;
-               ret = get_utf8(&b, b+i);
-               if (ret == WERR)
-                       ret = (unsigned char)buf[0];
-       } else {
-               i = 10;
-               buf[--i] = ch;
-               while (ch != WEOF && (ch & 0xc0) != 0xc0 && i > 0) {
-                       ch = doc_prev(p, m);
-                       buf[--i] = ch;
-               }
-               b = buf + i;
-               ret = get_utf8(&b, buf+10);
-               if (ret == WERR)
-                       ret = (unsigned char)buf[i];
+               doc_next(p, m);
        }
+       b = buf;
+       ret = get_utf8(&b, b+i);
+       if (ret == WERR)
+               ret = (unsigned char)buf[0];
        if (!move)
                mark_free(m);
-       return CHAR_RET(ret);
+       return ret;
 }
 
-DEF_CMD(utf8_char)
+static inline wint_t utf8_prev(struct pane *home safe, struct mark *mark safe,
+                              struct doc_ref *r, bool bytes)
 {
-       struct mark *m = ci->mark;
-       struct mark *end = ci->mark2;
-       int steps = ci->num;
-       int forward = steps > 0;
-       int ret = Einval;
+       int move = r == &mark->ref;
+       struct pane *p = home->parent;
+       wint_t ch;
+       struct mark *m = mark;
+       char buf[10];
+       const char *b;
+       int i;
+       wint_t ret;
 
-       if (!m)
-               return Enoarg;
-       if (end && mark_same(m, end))
-               return 1;
-       if (end && (end->seq < m->seq) != (steps < 0))
-               /* Can never cross 'end' */
-               return Einval;
-       while (steps && ret != CHAR_RET(WEOF) && (!end || !mark_same(m, end))) {
-               ret = utf8_step(ci->home, m, forward, 1);
-               steps -= forward*2 - 1;
+       if (move)
+               ch = doc_move(p, m, -1);
+       else
+               ch = doc_pending(p, m, -1);
+       if (ch == WEOF || (ch & 0x7f) == ch)
+               return ch;
+       if (!move) {
+               m = mark_dup(m);
+               doc_move(p, m, -1);
        }
-       if (end)
-               return 1 + (forward ? ci->num - steps : steps - ci->num);
-       if (ret == CHAR_RET(WEOF) || ci->num2 == 0)
-               return ret;
-       if (ci->num && (ci->num2 < 0) == forward)
-               return ret;
-       /* Want the 'next' char */
-       return utf8_step(ci->home, m, ci->num2 > 0, 0);
+       i = 10;
+       buf[--i] = ch;
+       while (ch != WEOF && (ch & 0xc0) != 0xc0 && i > 0) {
+               ch = doc_prev(p, m);
+               buf[--i] = ch;
+       }
+       b = buf + i;
+       ret = get_utf8(&b, buf+10);
+       if (ret == WERR)
+               ret = (unsigned char)buf[i];
+
+       if (!move)
+               mark_free(m);
+       return ret;
+}
+
+DEF_CMD(utf8_char)
+{
+       return do_char_byte(ci);
 }
 
 DEF_CMD(utf8_byte)