Просмотр исходного кода

WInput: use GString for buffer.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Andrew Borodin 3 лет назад
Родитель
Сommit
bf0dd8efb1

+ 74 - 114
lib/widget/input.c

@@ -156,9 +156,9 @@ delete_region (WInput * in, int start, int end)
 
     input_mark_cmd (in, FALSE);
     in->point = first;
-    last = str_offset_to_pos (in->buffer, last);
-    first = str_offset_to_pos (in->buffer, first);
-    str_move (in->buffer + first, in->buffer + last);
+    last = str_offset_to_pos (in->buffer->str, last);
+    first = str_offset_to_pos (in->buffer->str, first);
+    g_string_erase (in->buffer, first, last - first);
     in->charpoint = 0;
     in->need_push = TRUE;
 }
@@ -277,18 +277,15 @@ push_history (WInput * in, const char *text)
 static void
 move_buffer_backward (WInput * in, int start, int end)
 {
-    int i, pos, len;
     int str_len;
 
-    str_len = str_length (in->buffer);
+    str_len = str_length (in->buffer->str);
     if (start >= str_len || end > str_len + 1)
         return;
 
-    pos = str_offset_to_pos (in->buffer, start);
-    len = str_offset_to_pos (in->buffer, end) - pos;
-
-    for (i = pos; in->buffer[i + len - 1]; i++)
-        in->buffer[i] = in->buffer[i + len];
+    start = str_offset_to_pos (in->buffer->str, start);
+    end = str_offset_to_pos (in->buffer->str, end);
+    g_string_erase (in->buffer, start, end - start);
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -298,6 +295,7 @@ insert_char (WInput * in, int c_code)
 {
     int res;
     long m1, m2;
+    size_t ins_point;
 
     if (input_eval_marks (in, &m1, &m2))
         delete_region (in, m1, m2);
@@ -320,37 +318,11 @@ insert_char (WInput * in, int c_code)
     }
 
     in->need_push = TRUE;
-    if (strlen (in->buffer) + 1 + in->charpoint >= in->current_max_size)
-    {
-        /* Expand the buffer */
-        size_t new_length;
-        char *narea;
-
-        new_length = in->current_max_size + WIDGET (in)->cols + in->charpoint;
-        narea = g_try_renew (char, in->buffer, new_length);
-        if (narea != NULL)
-        {
-            in->buffer = narea;
-            in->current_max_size = new_length;
-        }
-    }
-
-    if (strlen (in->buffer) + in->charpoint < in->current_max_size)
-    {
-        size_t i;
-        /* bytes from begin */
-        size_t ins_point = str_offset_to_pos (in->buffer, in->point);
-        /* move chars */
-        size_t rest_bytes = strlen (in->buffer + ins_point);
-
-        for (i = rest_bytes + 1; i > 0; i--)
-            in->buffer[ins_point + i + in->charpoint - 1] = in->buffer[ins_point + i - 1];
-
-        memcpy (in->buffer + ins_point, in->charbuf, in->charpoint);
-        in->point++;
-    }
-
+    ins_point = str_offset_to_pos (in->buffer->str, in->point);
+    g_string_insert_len (in->buffer, ins_point, in->charbuf, in->charpoint);
+    in->point++;
     in->charpoint = 0;
+
     return MSG_HANDLED;
 }
 
@@ -368,7 +340,7 @@ beginning_of_line (WInput * in)
 static void
 end_of_line (WInput * in)
 {
-    in->point = str_length (in->buffer);
+    in->point = str_length (in->buffer->str);
     in->charpoint = 0;
 }
 
@@ -377,11 +349,14 @@ end_of_line (WInput * in)
 static void
 backward_char (WInput * in)
 {
-    const char *act;
-
-    act = in->buffer + str_offset_to_pos (in->buffer, in->point);
     if (in->point > 0)
-        in->point -= str_cprev_noncomb_char (&act, in->buffer);
+    {
+        const char *act;
+
+        act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
+        in->point -= str_cprev_noncomb_char (&act, in->buffer->str);
+    }
+
     in->charpoint = 0;
 }
 
@@ -392,7 +367,7 @@ forward_char (WInput * in)
 {
     const char *act;
 
-    act = in->buffer + str_offset_to_pos (in->buffer, in->point);
+    act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
     if (act[0] != '\0')
         in->point += str_cnext_noncomb_char (&act);
     in->charpoint = 0;
@@ -405,17 +380,13 @@ forward_word (WInput * in)
 {
     const char *p;
 
-    p = in->buffer + str_offset_to_pos (in->buffer, in->point);
-    while (p[0] != '\0' && (str_isspace (p) || str_ispunct (p)))
-    {
+    p = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
+
+    for (; p[0] != '\0' && (str_isspace (p) || str_ispunct (p)); in->point++)
         str_cnext_char (&p);
-        in->point++;
-    }
-    while (p[0] != '\0' && !str_isspace (p) && !str_ispunct (p))
-    {
+
+    for (; p[0] != '\0' && !str_isspace (p) && !str_ispunct (p); in->point++)
         str_cnext_char (&p);
-        in->point++;
-    }
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -425,9 +396,9 @@ backward_word (WInput * in)
 {
     const char *p;
 
-    p = in->buffer + str_offset_to_pos (in->buffer, in->point);
+    p = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
 
-    while (p != in->buffer)
+    for (; p != in->buffer->str; in->point--)
     {
         const char *p_tmp;
 
@@ -438,15 +409,13 @@ backward_word (WInput * in)
             p = p_tmp;
             break;
         }
-        in->point--;
     }
-    while (p != in->buffer)
+
+    for (; p != in->buffer->str; in->point--)
     {
         str_cprev_char (&p);
         if (str_isspace (p) || str_ispunct (p))
             break;
-
-        in->point--;
     }
 }
 
@@ -455,13 +424,14 @@ backward_word (WInput * in)
 static void
 backward_delete (WInput * in)
 {
-    const char *act = in->buffer + str_offset_to_pos (in->buffer, in->point);
+    const char *act;
     int start;
 
     if (in->point == 0)
         return;
 
-    start = in->point - str_cprev_noncomb_char (&act, in->buffer);
+    act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
+    start = in->point - str_cprev_noncomb_char (&act, in->buffer->str);
     move_buffer_backward (in, start, in->point);
     in->charpoint = 0;
     in->need_push = TRUE;
@@ -474,11 +444,10 @@ static void
 delete_char (WInput * in)
 {
     const char *act;
-    int end = in->point;
-
-    act = in->buffer + str_offset_to_pos (in->buffer, in->point);
-    end += str_cnext_noncomb_char (&act);
+    int end;
 
+    act = in->buffer->str + str_offset_to_pos (in->buffer->str, in->point);
+    end = in->point + str_cnext_noncomb_char (&act);
     move_buffer_backward (in, in->point, end);
     in->charpoint = 0;
     in->need_push = TRUE;
@@ -503,10 +472,10 @@ copy_region (WInput * in, int start, int end)
 
     g_free (kill_buffer);
 
-    first = str_offset_to_pos (in->buffer, first);
-    last = str_offset_to_pos (in->buffer, last);
+    first = str_offset_to_pos (in->buffer->str, first);
+    last = str_offset_to_pos (in->buffer->str, last);
 
-    kill_buffer = g_strndup (in->buffer + first, last - first);
+    kill_buffer = g_strndup (in->buffer->str + first, last - first);
 
     mc_event_raise (MCEVENT_GROUP_CORE, "clipboard_text_to_file", kill_buffer);
     /* try use external clipboard utility */
@@ -569,10 +538,10 @@ kill_line (WInput * in)
 {
     int chp;
 
-    chp = str_offset_to_pos (in->buffer, in->point);
+    chp = str_offset_to_pos (in->buffer->str, in->point);
     g_free (kill_buffer);
-    kill_buffer = g_strdup (&in->buffer[chp]);
-    in->buffer[chp] = '\0';
+    kill_buffer = g_strndup (in->buffer->str + chp, in->buffer->len - chp);
+    g_string_set_size (in->buffer, chp);
     in->charpoint = 0;
 }
 
@@ -582,7 +551,7 @@ static void
 clear_line (WInput * in)
 {
     in->need_push = TRUE;
-    in->buffer[0] = '\0';
+    g_string_set_size (in->buffer, 0);
     in->point = 0;
     in->mark = -1;
     in->charpoint = 0;
@@ -623,7 +592,7 @@ hist_prev (WInput * in)
         return;
 
     if (in->need_push)
-        push_history (in, in->buffer);
+        push_history (in, in->buffer->str);
 
     prev = g_list_previous (in->history.current);
     if (prev != NULL)
@@ -644,7 +613,7 @@ hist_next (WInput * in)
 
     if (in->need_push)
     {
-        push_history (in, in->buffer);
+        push_history (in, in->buffer->str);
         input_assign_text (in, "");
         return;
     }
@@ -672,7 +641,7 @@ hist_next (WInput * in)
 static void
 port_region_marked_for_delete (WInput * in)
 {
-    in->buffer[0] = '\0';
+    g_string_set_size (in->buffer, 0);
     in->point = 0;
     in->first = FALSE;
     in->charpoint = 0;
@@ -875,7 +844,7 @@ input_save_history (const gchar * event_group_name, const gchar * event_name,
     {
         ev_history_load_save_t *ev = (ev_history_load_save_t *) data;
 
-        push_history (in, in->buffer);
+        push_history (in, in->buffer->str);
         if (in->history.changed)
             mc_config_history_save (ev->cfg, in->history.name, in->history.list);
         in->history.changed = FALSE;
@@ -905,7 +874,7 @@ input_destroy (WInput * in)
         g_list_free_full (in->history.list, g_free);
     }
     g_free (in->history.name);
-    g_free (in->buffer);
+    g_string_free (in->buffer, TRUE);
     MC_PTR_FREE (kill_buffer);
 }
 
@@ -922,10 +891,10 @@ input_screen_to_point (const WInput * in, int x)
     if (x < 0)
         return 0;
 
-    if (x < str_term_width1 (in->buffer))
-        return str_column_to_pos (in->buffer, x);
+    if (x < str_term_width1 (in->buffer->str))
+        return str_column_to_pos (in->buffer->str, x);
 
-    return str_length (in->buffer);
+    return str_length (in->buffer->str);
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -1006,8 +975,7 @@ input_new (int y, int x, const int *colors, int width, const char *def_text,
     in->strip_password = FALSE;
 
     /* in->buffer will be corrected in "history_load" event handler */
-    in->current_max_size = width + 1;
-    in->buffer = g_new0 (char, in->current_max_size);
+    in->buffer = g_string_sized_new (width);
 
     /* init completions before input_assign_text() call */
     in->completions = NULL;
@@ -1093,7 +1061,7 @@ input_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void *d
         return MSG_HANDLED;
 
     case MSG_CURSOR:
-        widget_gotoyx (in, 0, str_term_width2 (in->buffer, in->point) - in->term_first_shown);
+        widget_gotoyx (in, 0, str_term_width2 (in->buffer->str, in->point) - in->term_first_shown);
         return MSG_HANDLED;
 
     case MSG_DESTROY:
@@ -1170,9 +1138,6 @@ input_handle_char (WInput * in, int key)
 void
 input_assign_text (WInput * in, const char *text)
 {
-    Widget *w = WIDGET (in);
-    size_t text_len, buffer_len;
-
     if (text == NULL)
         text = "";
 
@@ -1180,14 +1145,8 @@ input_assign_text (WInput * in, const char *text)
     in->mark = -1;
     in->need_push = TRUE;
     in->charpoint = 0;
-
-    text_len = strlen (text);
-    buffer_len = 1 + MAX ((size_t) w->cols, text_len);
-    in->current_max_size = buffer_len;
-    if (buffer_len > (size_t) w->cols)
-        in->buffer = g_realloc (in->buffer, buffer_len);
-    memmove (in->buffer, text, text_len + 1);
-    in->point = str_length (in->buffer);
+    g_string_assign (in->buffer, text);
+    in->point = str_length (in->buffer->str);
     input_update (in, TRUE);
 }
 
@@ -1207,7 +1166,7 @@ input_get_text (const WInput * in)
     if (input_is_empty (in))
         return NULL;
 
-    return g_strdup (in->buffer);
+    return g_strndup (in->buffer->str, in->buffer->len);
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -1221,7 +1180,7 @@ input_is_empty (const WInput * in)
     /* if in != NULL, in->buffer must be created */
     g_assert (in->buffer != NULL);
 
-    return in->buffer[0] == '\0';
+    return in->buffer->len == 0;
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -1246,7 +1205,7 @@ input_set_point (WInput * in, int pos)
 {
     int max_pos;
 
-    max_pos = str_length (in->buffer);
+    max_pos = str_length (in->buffer->str);
     pos = MIN (pos, max_pos);
     if (pos != in->point)
         input_complete_free (in);
@@ -1279,12 +1238,12 @@ input_update (WInput * in, gboolean clear_first)
     if (should_show_history_button (in))
         has_history = HISTORY_BUTTON_WIDTH;
 
-    buf_len = str_length (in->buffer);
+    buf_len = str_length (in->buffer->str);
 
     /* Adjust the mark */
     in->mark = MIN (in->mark, buf_len);
 
-    pw = str_term_width2 (in->buffer, in->point);
+    pw = str_term_width2 (in->buffer->str, in->point);
 
     /* Make the point visible */
     if ((pw < in->term_first_shown) || (pw >= in->term_first_shown + w->cols - has_history))
@@ -1309,7 +1268,7 @@ input_update (WInput * in, gboolean clear_first)
     if (!in->is_password)
     {
         if (in->mark < 0)
-            tty_print_string (str_term_substring (in->buffer, in->term_first_shown,
+            tty_print_string (str_term_substring (in->buffer->str, in->term_first_shown,
                                                   w->cols - has_history));
         else
         {
@@ -1318,26 +1277,27 @@ input_update (WInput * in, gboolean clear_first)
             if (input_eval_marks (in, &m1, &m2))
             {
                 tty_setcolor (in->color[WINPUTC_MAIN]);
-                cp = str_term_substring (in->buffer, in->term_first_shown, w->cols - has_history);
+                cp = str_term_substring (in->buffer->str, in->term_first_shown,
+                                         w->cols - has_history);
                 tty_print_string (cp);
                 tty_setcolor (in->color[WINPUTC_MARK]);
                 if (m1 < in->term_first_shown)
                 {
                     widget_gotoyx (in, 0, 0);
-                    tty_print_string (str_term_substring
-                                      (in->buffer, in->term_first_shown,
-                                       m2 - in->term_first_shown));
+                    m1 = in->term_first_shown;
+                    m2 -= m1;
                 }
                 else
                 {
-                    int sel_width, buf_width;
+                    int buf_width;
 
                     widget_gotoyx (in, 0, m1 - in->term_first_shown);
-                    buf_width = str_term_width2 (in->buffer, m1);
-                    sel_width =
-                        MIN (m2 - m1, (w->cols - has_history) - (buf_width - in->term_first_shown));
-                    tty_print_string (str_term_substring (in->buffer, m1, sel_width));
+                    buf_width = str_term_width2 (in->buffer->str, m1);
+                    m2 = MIN (m2 - m1,
+                              (w->cols - has_history) - (buf_width - in->term_first_shown));
                 }
+
+                tty_print_string (str_term_substring (in->buffer->str, m1, m2));
             }
         }
     }
@@ -1345,7 +1305,7 @@ input_update (WInput * in, gboolean clear_first)
     {
         int i;
 
-        cp = str_term_substring (in->buffer, in->term_first_shown, w->cols - has_history);
+        cp = str_term_substring (in->buffer->str, in->term_first_shown, w->cols - has_history);
         tty_setcolor (in->color[WINPUTC_MAIN]);
         for (i = 0; i < w->cols - has_history; i++)
         {
@@ -1386,9 +1346,9 @@ input_disable_update (WInput * in)
 void
 input_clean (WInput * in)
 {
-    push_history (in, in->buffer);
+    push_history (in, in->buffer->str);
     in->need_push = TRUE;
-    in->buffer[0] = '\0';
+    g_string_set_size (in->buffer, 0);
     in->point = 0;
     in->charpoint = 0;
     in->mark = -1;

+ 2 - 2
lib/widget/input.h

@@ -46,16 +46,16 @@ typedef int input_colors_t[WINPUTC_COUNT_COLORS];
 typedef struct
 {
     Widget widget;
+
+    GString *buffer;
     const int *color;
     int point;                  /* cursor position in the input line in characters */
     int mark;                   /* the mark position in characters; negative value means no marked text */
     int term_first_shown;       /* column of the first shown character */
-    size_t current_max_size;    /* maximum length of input line (bytes) */
     gboolean first;             /* is first keystroke? */
     int disable_update;         /* do we want to skip updates? */
     gboolean is_password;       /* is this a password input line? */
     gboolean init_from_history; /* init text will be get from history */
-    char *buffer;               /* pointer to editing buffer */
     gboolean need_push;         /* need to push the current Input on hist? */
     gboolean strip_password;    /* need to strip password before placing string to history */
     char **completions;         /* possible completions array */

+ 44 - 35
lib/widget/input_complete.c

@@ -8,7 +8,7 @@
    Written by:
    Jakub Jelinek, 1995
    Slava Zanko <slavazanko@gmail.com>, 2013
-   Andrew Borodin <aborodin@vmail.ru>, 2013
+   Andrew Borodin <aborodin@vmail.ru>, 2013-2022
 
    This file is part of the Midnight Commander.
 
@@ -980,38 +980,47 @@ insert_text (WInput * in, char *text, ssize_t size)
 {
     size_t text_len;
     int buff_len;
+    ssize_t new_size;
 
     text_len = strlen (text);
-    buff_len = str_length (in->buffer);
+    buff_len = str_length (in->buffer->str);
     if (size < 0)
         size = (ssize_t) text_len;
     else
         size = MIN (size, (ssize_t) text_len);
-    size += start - end;
-    if (strlen (in->buffer) + size >= (size_t) in->current_max_size)
+
+    new_size = size + start - end;
+    if (new_size != 0)
     {
-        /* Expand the buffer */
-        char *narea;
-        Widget *w = WIDGET (in);
+        /* make a hole within buffer */
+
+        size_t tail_len;
 
-        narea = g_try_realloc (in->buffer, in->current_max_size + size + w->cols);
-        if (narea != NULL)
+        tail_len = in->buffer->len - end;
+        if (tail_len != 0)
         {
-            in->buffer = narea;
-            in->current_max_size += size + w->cols;
+            char *tail;
+            size_t hole_end;
+
+            tail = g_strndup (in->buffer->str + end, tail_len);
+
+            hole_end = end + new_size;
+            if (in->buffer->len < hole_end)
+                g_string_set_size (in->buffer, hole_end + tail_len);
+
+            g_string_overwrite_len (in->buffer, hole_end, tail, tail_len);
+
+            g_free (tail);
         }
     }
-    if (strlen (in->buffer) + 1 < (size_t) in->current_max_size)
-    {
-        if (size != 0)
-            memmove (in->buffer + end + size, in->buffer + end, strlen (&in->buffer[end]) + 1);
-        memmove (in->buffer + start, text, size - (start - end));
-        in->point += str_length (in->buffer) - buff_len;
-        input_update (in, TRUE);
-        end += size;
-    }
 
-    return size != 0;
+    g_string_overwrite_len (in->buffer, start, text, size);
+
+    in->point += str_length (in->buffer->str) - buff_len;
+    input_update (in, TRUE);
+    end += new_size;
+
+    return new_size != 0;
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -1047,7 +1056,7 @@ complete_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
             /* Refill the list box and start again */
             else if (end == min_end)
             {
-                end = str_get_prev_char (&input->buffer[end]) - input->buffer;
+                end = str_get_prev_char (input->buffer->str + end) - input->buffer->str;
                 input_handle_char (input, parm);
                 h->ret_value = B_USER;
                 dlg_stop (h);
@@ -1058,14 +1067,14 @@ complete_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
                 int i;
                 GList *e;
 
-                new_end = str_get_prev_char (&input->buffer[end]) - input->buffer;
+                new_end = str_get_prev_char (input->buffer->str + end) - input->buffer->str;
 
                 for (i = 0, e = listbox_get_first_link (LISTBOX (g->current->data));
                      e != NULL; i++, e = g_list_next (e))
                 {
                     WLEntry *le = LENTRY (e->data);
 
-                    if (strncmp (input->buffer + start, le->text, new_end - start) == 0)
+                    if (strncmp (input->buffer->str + start, le->text, new_end - start) == 0)
                     {
                         listbox_select_entry (LISTBOX (g->current->data), i);
                         end = new_end;
@@ -1119,8 +1128,8 @@ complete_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
                 {
                     WLEntry *le = LENTRY (e->data);
 
-                    if (strncmp (input->buffer + start, le->text, end - start) == 0
-                        && strncmp (&le->text[end - start], buff, bl) == 0)
+                    if (strncmp (input->buffer->str + start, le->text, end - start) == 0
+                        && strncmp (le->text + end - start, buff, bl) == 0)
                     {
                         if (need_redraw == 0)
                         {
@@ -1199,7 +1208,7 @@ complete_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, void
 static gboolean
 complete_engine (WInput * in, int what_to_do)
 {
-    if (in->completions != NULL && str_offset_to_pos (in->buffer, in->point) != end)
+    if (in->completions != NULL && str_offset_to_pos (in->buffer->str, in->point) != end)
         input_complete_free (in);
 
     if (in->completions == NULL)
@@ -1408,9 +1417,9 @@ complete_engine_fill_completions (WInput * in)
 
     word_separators = (in->completion_flags & INPUT_COMPLETE_SHELL_ESC) ? " \t;|<>" : "\t;|<>";
 
-    end = str_offset_to_pos (in->buffer, in->point);
+    end = str_offset_to_pos (in->buffer->str, in->point);
 
-    s = in->buffer;
+    s = in->buffer->str;
     if (in->point != 0)
     {
         /* get symbol before in->point */
@@ -1420,20 +1429,20 @@ complete_engine_fill_completions (WInput * in)
             str_next_char (&s);
     }
 
-    for (; s >= in->buffer; str_prev_char (&s))
+    for (; s >= in->buffer->str; str_prev_char (&s))
     {
-        start = s - in->buffer;
-        if (strchr (word_separators, *s) != NULL && !strutils_is_char_escaped (in->buffer, s))
+        start = s - in->buffer->str;
+        if (strchr (word_separators, *s) != NULL && !strutils_is_char_escaped (in->buffer->str, s))
             break;
     }
 
     if (start < end)
     {
         str_next_char (&s);
-        start = s - in->buffer;
+        start = s - in->buffer->str;
     }
 
-    in->completions = try_complete (in->buffer, &start, &end, in->completion_flags);
+    in->completions = try_complete (in->buffer->str, &start, &end, in->completion_flags);
 }
 
 /* --------------------------------------------------------------------------------------------- */
@@ -1444,7 +1453,7 @@ input_complete (WInput * in)
 {
     int engine_flags;
 
-    if (!str_is_valid_string (in->buffer))
+    if (!str_is_valid_string (in->buffer->str))
         return;
 
     if (in->completions != NULL)

+ 1 - 1
lib/widget/quick.c

@@ -597,7 +597,7 @@ quick_dialog_skip (quick_dialog_t * quick_dlg, int nskip)
             case quick_input:
                 if ((item->quick_widget->u.input.completion_flags & INPUT_COMPLETE_CD) != 0)
                     *item->quick_widget->u.input.result =
-                        tilde_expand (INPUT (item->widget)->buffer);
+                        tilde_expand (INPUT (item->widget)->buffer->str);
                 else
                     *item->quick_widget->u.input.result = input_get_text (INPUT (item->widget));
                 break;

+ 2 - 2
src/filemanager/cmd.c

@@ -6,7 +6,7 @@
    Free Software Foundation, Inc.
 
    Written by:
-   Andrew Borodin <aborodin@vmail.ru>, 2013-2015
+   Andrew Borodin <aborodin@vmail.ru>, 2013-2022
 
    This file is part of the Midnight Commander.
 
@@ -622,7 +622,7 @@ view_filtered_cmd (const WPanel * panel)
     if (input_is_empty (cmdline))
         initial_command = selection (panel)->fname->str;
     else
-        initial_command = cmdline->buffer;
+        initial_command = cmdline->buffer->str;
 
     command =
         input_dialog (_("Filtered view"),

+ 2 - 2
src/filemanager/command.c

@@ -9,7 +9,7 @@
 
    Written by:
    Slava Zanko <slavazanko@gmail.com>, 2013
-   Andrew Borodin <aborodin@vmail.ru>, 2020
+   Andrew Borodin <aborodin@vmail.ru>, 2011-2022
 
    This file is part of the Midnight Commander.
 
@@ -81,7 +81,7 @@ static input_colors_t command_colors;
 static cb_ret_t
 enter (WInput * lc_cmdline)
 {
-    char *cmd = lc_cmdline->buffer;
+    const char *cmd = lc_cmdline->buffer->str;
 
     if (!command_prompt)
         return MSG_HANDLED;

+ 2 - 2
src/filemanager/filemanager.c

@@ -1462,10 +1462,10 @@ handle_cmdline_enter (void)
 {
     size_t i;
 
-    for (i = 0; cmdline->buffer[i] != '\0' && whitespace (cmdline->buffer[i]); i++)
+    for (i = 0; i < cmdline->buffer->len && whitespace (cmdline->buffer->str[i]); i++)
         ;
 
-    if (cmdline->buffer[i] != '\0')
+    if (i != cmdline->buffer->len)
     {
         send_message (cmdline, NULL, MSG_KEY, '\n', NULL);
         return TRUE;

+ 7 - 6
src/filemanager/find.c

@@ -501,7 +501,7 @@ find_parm_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, voi
 
         /* check filename regexp */
         if (!file_pattern_cbox->state && !input_is_empty (in_name)
-            && !find_check_regexp (in_name->buffer))
+            && !find_check_regexp (in_name->buffer->str))
         {
             /* Don't stop the dialog */
             widget_set_state (w, WST_ACTIVE, TRUE);
@@ -511,7 +511,8 @@ find_parm_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, voi
         }
 
         /* check content regexp */
-        if (content_regexp_cbox->state && !content_is_empty && !find_check_regexp (in_with->buffer))
+        if (content_regexp_cbox->state && !content_is_empty
+            && !find_check_regexp (in_with->buffer->str))
         {
             /* Don't stop the dialog */
             widget_set_state (w, WST_ACTIVE, TRUE);
@@ -784,10 +785,10 @@ find_parameters (WPanel * panel, char **start_dir, ssize_t * start_dir_len,
         {
             const char *temp_dir;
 
-            if (input_is_empty (in_start) || DIR_IS_DOT (in_start->buffer))
+            if (input_is_empty (in_start) || DIR_IS_DOT (in_start->buffer->str))
                 temp_dir = vfs_path_as_str (panel->cwd_vpath);
             else
-                temp_dir = in_start->buffer;
+                temp_dir = in_start->buffer->str;
 
             if (in_start_dir != INPUT_LAST_TEXT)
                 g_free (in_start_dir);
@@ -826,7 +827,7 @@ find_parameters (WPanel * panel, char **start_dir, ssize_t * start_dir_len,
             *pattern = input_get_text (in_name);
             if (*pattern == NULL)
                 *pattern = g_strdup (options.file_pattern ? "*" : ".*");
-            *start_dir = !input_is_empty (in_start) ? in_start->buffer : (char *) ".";
+            *start_dir = !input_is_empty (in_start) ? in_start->buffer->str : (char *) ".";
             if (in_start_dir != INPUT_LAST_TEXT)
                 g_free (in_start_dir);
             in_start_dir = g_strdup (*start_dir);
@@ -857,7 +858,7 @@ find_parameters (WPanel * panel, char **start_dir, ssize_t * start_dir_len,
             }
 
             if (!options.ignore_dirs_enable || input_is_empty (in_ignore)
-                || DIR_IS_DOT (in_ignore->buffer))
+                || DIR_IS_DOT (in_ignore->buffer->str))
                 *ignore_dirs = NULL;
             else
                 *ignore_dirs = input_get_text (in_ignore);

+ 6 - 6
src/subshell/common.c

@@ -1467,16 +1467,16 @@ invoke_subshell (const char *command, int how, vfs_path_t ** new_dir_vpath)
 
                 /* Check to make sure there are no non text characters in the command buffer,
                  * such as tab, or newline, as this could cause problems. */
-                for (i = 0; cmdline->buffer[i] != '\0'; i++)
-                    if ((unsigned char) cmdline->buffer[i] < 32
-                        || (unsigned char) cmdline->buffer[i] == 127)
-                        cmdline->buffer[i] = ' ';
+                for (i = 0; i < cmdline->buffer->len; i++)
+                    if ((unsigned char) cmdline->buffer->str[i] < 32
+                        || (unsigned char) cmdline->buffer->str[i] == 127)
+                        g_string_overwrite_len (cmdline->buffer, i, " ", 1);
 
                 /* Write the command buffer to the subshell. */
-                write_all (mc_global.tty.subshell_pty, cmdline->buffer, strlen (cmdline->buffer));
+                write_all (mc_global.tty.subshell_pty, cmdline->buffer->str, cmdline->buffer->len);
 
                 /* Put the cursor in the correct place in the subshell. */
-                pos = str_length (cmdline->buffer) - cmdline->point;
+                pos = str_length (cmdline->buffer->str) - cmdline->point;
                 for (i = 0; i < (size_t) pos; i++)
                     write_all (mc_global.tty.subshell_pty, ESC_STR "[D", 3);
             }

+ 1 - 3
tests/lib/widget/complete_engine.c

@@ -198,10 +198,8 @@ START_PARAMETRIZED_TEST (test_complete_engine_fill_completions,
     /* given */
     WInput *w_input;
 
-    w_input = g_new (WInput, 1);
-    w_input->buffer = g_strdup (data->input_buffer);
+    w_input = input_new (1, 1, NULL, 100, data->input_buffer, NULL, data->input_completion_flags);
     w_input->point = data->input_point;
-    w_input->completion_flags = data->input_completion_flags;
 
     /* when */
     complete_engine_fill_completions (w_input);