billiob pushed a commit to branch master.

http://git.enlightenment.org/apps/terminology.git/commit/?id=688bf414e4622e4fd6d2b2cd377eba569a39f580

commit 688bf414e4622e4fd6d2b2cd377eba569a39f580
Author: Boris Faure <bill...@gmail.com>
Date:   Sun Mar 8 20:22:44 2015 +0100

     right trim selections
    
    Also add a (near-dumb) string buffer abstraction because working with
    Eina_Strbuf, an opaque structure is a PITA.
---
 src/bin/termio.c     | 117 +++++++++++++++++++++++++++++++++++++++------------
 src/bin/termio.h     |   2 +-
 src/bin/termiolink.c |  11 ++---
 3 files changed, 98 insertions(+), 32 deletions(-)

diff --git a/src/bin/termio.c b/src/bin/termio.c
index b092d0a..50818a6 100644
--- a/src/bin/termio.c
+++ b/src/bin/termio.c
@@ -1935,18 +1935,62 @@ end:
 /* }}} */
 /* {{{ Selection */
 
+struct termio_sb {
+   char *buf;
+   size_t len;
+   size_t alloc;
+};
+
+static int
+_sb_add(struct termio_sb *sb, const char *s, size_t len)
+{
+   size_t new_len = sb->len + len;
+
+   if (new_len >= sb->alloc)
+     {
+        size_t new_alloc = ((new_len + 15) / 16) * 24;
+        char *new_buf;
+
+        new_buf = realloc(sb->buf, new_alloc);
+        if (new_buf == NULL)
+          return -1;
+        sb->buf = new_buf;
+        sb->alloc = new_alloc;
+     }
+   memcpy(sb->buf + sb->len, s, len);
+   sb->len += len;
+   sb->buf[sb->len] = '\0';
+   return 0;
+}
+
+/* unlike eina_strbuf_rtrim, only trims \t, \f, ' ' */
+void
+_sb_spaces_rtrim(struct termio_sb *sb)
+{
+   if (!sb->buf)
+     return;
+
+   while (sb->len > 0)
+     {
+        char c = sb->buf[sb->len - 1];
+        if ((c != ' ') && (c != '\t') && (c != '\f'))
+            break;
+        sb->len--;
+     }
+   sb->buf[sb->len] = '\0';
+}
+
+
 char *
 termio_selection_get(Evas_Object *obj, int c1x, int c1y, int c2x, int c2y,
-                     size_t *len)
+                     size_t *lenp,
+                     Eina_Bool rtrim)
 {
    Termio *sd = evas_object_smart_data_get(obj);
-   Eina_Strbuf *sb;
-   char *s;
+   struct termio_sb sb = {.buf = NULL, .len = 0, .alloc = 0};
    int x, y;
-   size_t len_backup;
 
    EINA_SAFETY_ON_NULL_RETURN_VAL(sd, NULL);
-   sb = eina_strbuf_new();
    termpty_cellcomp_freeze(sd->pty);
    for (y = c1y; y <= c2y; y++)
      {
@@ -1960,7 +2004,9 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, 
int c2x, int c2y,
         if (w > sd->grid.w) w = sd->grid.w;
         if (y == c1y && c1x >= w)
           {
-             eina_strbuf_append_char(sb, '\n');
+             if (rtrim)
+               _sb_spaces_rtrim(&sb);
+             if (_sb_add(&sb, "\n", 1) < 0) goto err;
              continue;
           }
         start_x = c1x;
@@ -1993,12 +2039,16 @@ termio_selection_get(Evas_Object *obj, int c1x, int 
c1y, int c2x, int c2y,
                {
                   last0 = -1;
                   if ((y != c2y) || (x != end_x))
-                    eina_strbuf_append_char(sb, '\n');
+                    {
+                       if (rtrim)
+                         _sb_spaces_rtrim(&sb);
+                       if (_sb_add(&sb, "\n", 1) < 0) goto err;
+                    }
                   break;
                }
              else if (cells[x].att.tab)
                {
-                  eina_strbuf_append_char(sb, '\t');
+                  if (_sb_add(&sb, "\t", 1) < 0) goto err;
                   x = ((x + 8) / 8) * 8;
                   x--;
                }
@@ -2013,18 +2063,22 @@ termio_selection_get(Evas_Object *obj, int c1x, int 
c1y, int c2x, int c2y,
                        last0 = -1;
                        while (v >= 0)
                          {
-                            eina_strbuf_append_char(sb, ' ');
+                            if (_sb_add(&sb, " ", 1) < 0) goto err;
                             v--;
                          }
                     }
                   txtlen = codepoint_to_utf8(cells[x].codepoint, txt);
                   if (txtlen > 0)
-                    eina_strbuf_append_length(sb, txt, txtlen);
+                    if (_sb_add(&sb, txt, txtlen) < 0) goto err;
                   if ((x == (w - 1)) &&
                       ((x != c2x) || (y != c2y)))
                     {
                        if (!cells[x].att.autowrapped)
-                         eina_strbuf_append_char(sb, '\n');
+                         {
+                            if (rtrim)
+                              _sb_spaces_rtrim(&sb);
+                            if (_sb_add(&sb, "\n", 1) < 0) goto err;
+                         }
                     }
                }
           }
@@ -2053,7 +2107,12 @@ termio_selection_get(Evas_Object *obj, int c1x, int c1y, 
int c2x, int c2y,
                             break;
                          }
                     }
-                  if (!have_more) eina_strbuf_append_char(sb, '\n');
+                  if (!have_more)
+                    {
+                       if (rtrim)
+                         _sb_spaces_rtrim(&sb);
+                       if (_sb_add(&sb, "\n", 1) < 0) goto err;
+                    }
                   else
                     {
                        for (x = last0; x <= end_x; x++)
@@ -2067,25 +2126,30 @@ termio_selection_get(Evas_Object *obj, int c1x, int 
c1y, int c2x, int c2y,
                               }
 #endif
                             if (x >= w) break;
-                            eina_strbuf_append_char(sb, ' ');
+                            if (_sb_add(&sb, " ", 1) < 0) goto err;
                          }
                     }
                }
-             else eina_strbuf_append_char(sb, '\n');
+             else
+               {
+                  if (rtrim)
+                    _sb_spaces_rtrim(&sb);
+                  if (_sb_add(&sb, "\n", 1) < 0) goto err;
+               }
           }
      }
    termpty_cellcomp_thaw(sd->pty);
 
-   if (!len) len = &len_backup;
-   *len = eina_strbuf_length_get(sb);
-   if (!*len)
-     {
-        eina_strbuf_free(sb);
-        return NULL;
-     }
-   s = eina_strbuf_string_steal(sb);
-   eina_strbuf_free(sb);
-   return s;
+   if (rtrim)
+     _sb_spaces_rtrim(&sb);
+
+   if (lenp)
+     *lenp = sb.len;
+
+   return sb.buf;
+err:
+   free(sb.buf);
+   return NULL;
 }
 
 
@@ -2212,7 +2276,7 @@ termio_take_selection(Evas_Object *obj, Elm_Sel_Type type)
         for (i = start_y; i <= end_y; i++)
           {
              char *tmp = termio_selection_get(obj, start_x, i, end_x, i,
-                                              &len);
+                                              &len, EINA_TRUE);
 
              if (tmp)
                {
@@ -2233,7 +2297,8 @@ termio_take_selection(Evas_Object *obj, Elm_Sel_Type type)
      }
    else if ((start_x != end_x) || (start_y != end_y))
      {
-        s = termio_selection_get(obj, start_x, start_y, end_x, end_y, &len);
+        s = termio_selection_get(obj, start_x, start_y, end_x, end_y, &len,
+                                 EINA_TRUE);
      }
 
    if (s)
diff --git a/src/bin/termio.h b/src/bin/termio.h
index d18ebaf..56dfeb7 100644
--- a/src/bin/termio.h
+++ b/src/bin/termio.h
@@ -13,7 +13,7 @@ void         termio_theme_set(Evas_Object *obj, Evas_Object 
*theme);
 Evas_Object *termio_theme_get(Evas_Object *obj);
 char        *termio_selection_get(Evas_Object *obj,
                                   int c1x, int c1y, int c2x, int c2y,
-                                  size_t *len);
+                                  size_t *len, Eina_Bool right_trim);
 Eina_Bool    termio_selection_exists(const Evas_Object *obj);
 void termio_scroll_delta(Evas_Object *obj, int delta, int by_page);
 void termio_scroll_set(Evas_Object *obj, int scroll);
diff --git a/src/bin/termiolink.c b/src/bin/termiolink.c
index ad6542d..c0151b1 100644
--- a/src/bin/termiolink.c
+++ b/src/bin/termiolink.c
@@ -112,7 +112,7 @@ _termio_link_find(Evas_Object *obj, int cx, int cy,
    for (;;)
      {
         prev_len = len;
-        s = termio_selection_get(obj, x1, y1 - sc, x2, y2 - sc, &len);
+        s = termio_selection_get(obj, x1, y1 - sc, x2, y2 - sc, &len, 
EINA_FALSE);
         if (!s) break;
         if (goback)
           {
@@ -125,7 +125,7 @@ _termio_link_find(Evas_Object *obj, int cx, int cy,
                   coord_back(&x1, &y1, w, h);
                   free(s);
                   s = termio_selection_get(obj, x1, y1 - sc, x2, y2 - sc,
-                                           &len);
+                                           &len, EINA_FALSE);
                   if (!s) break;
                   switch (s[0])
                     {
@@ -142,7 +142,7 @@ _termio_link_find(Evas_Object *obj, int cx, int cy,
                   free(s);
                   prev_len = len;
                   s = termio_selection_get(obj, x1, y1 - sc, x2, y2 - sc,
-                                           &len);
+                                           &len, EINA_FALSE);
                   if (!s) break;
                }
              else
@@ -164,7 +164,7 @@ _termio_link_find(Evas_Object *obj, int cx, int cy,
                        goforward = EINA_TRUE;
                        free(s);
                        s = termio_selection_get(obj, x1, y1 - sc, x2, y2 - sc,
-                                                &len);
+                                                &len, EINA_FALSE);
                        if (!s) break;
                     }
                }
@@ -197,7 +197,8 @@ _termio_link_find(Evas_Object *obj, int cx, int cy,
         if ((!goback) && (!goforward))
           {
              free(s);
-             s = termio_selection_get(obj, x1, y1 - sc, x2, y2 - sc, &len);
+             s = termio_selection_get(obj, x1, y1 - sc, x2, y2 - sc, &len,
+                                      EINA_FALSE);
              break;
           }
         free(s);

-- 


Reply via email to