Browse Source

(examine_cd): refactoring: use GString.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
Andrew Borodin 6 years ago
parent
commit
aa9d18e3ed
2 changed files with 33 additions and 32 deletions
  1. 23 32
      src/filemanager/command.c
  2. 10 0
      tests/src/filemanager/examine_cd.c

+ 23 - 32
src/filemanager/command.c

@@ -94,55 +94,56 @@ static input_colors_t command_colors;
 static char *
 examine_cd (const char *_path)
 {
+    /* *INDENT-OFF* */
     typedef enum
-    { copy_sym, subst_var } state_t;
+    {
+        copy_sym,
+        subst_var
+    } state_t;
+    /* *INDENT-ON* */
 
     state_t state = copy_sym;
-    char *q;
-    size_t qlen;
+    GString *q;
     char *path_tilde, *path;
-    char *p, *r;
+    char *p;
 
     /* Tilde expansion */
     path = strutils_shell_unescape (_path);
     path_tilde = tilde_expand (path);
     g_free (path);
 
-    /* Leave space for further expansion */
-    qlen = strlen (path_tilde) + MC_MAXPATHLEN;
-    q = g_malloc (qlen);
+    q = g_string_sized_new (32);
 
     /* Variable expansion */
-    for (p = path_tilde, r = q; *p != '\0' && r < q + MC_MAXPATHLEN;)
+    for (p = path_tilde; *p != '\0';)
     {
         switch (state)
         {
         case copy_sym:
             if (p[0] == '\\' && p[1] == '$')
             {
-                /* skip backslash */
-                p++;
-                /* copy dollar */
-                *(r++) = *(p++);
+                g_string_append_c (q, '$');
+                p += 2;
             }
             else if (p[0] != '$' || p[1] == '[' || p[1] == '(')
-                *(r++) = *(p++);
+            {
+                g_string_append_c (q, *p);
+                p++;
+            }
             else
                 state = subst_var;
             break;
 
         case subst_var:
             {
-                char *s;
+                char *s = NULL;
                 char c;
-                const char *t;
+                const char *t = NULL;
 
                 /* skip dollar */
                 p++;
 
-                if (p[0] != '{')
-                    s = NULL;
-                else
+                if (p[0] == '{')
                 {
                     p++;
                     s = strchr (p, '}');
@@ -157,21 +158,13 @@ examine_cd (const char *_path)
                 *s = c;
                 if (t == NULL)
                 {
-                    *(r++) = '$';
+                    g_string_append_c (q, '$');
                     if (p[-1] != '$')
-                        *(r++) = '{';
+                        g_string_append_c (q, '{');
                 }
                 else
                 {
-                    size_t tlen;
-
-                    tlen = strlen (t);
-
-                    if (r + tlen < q + MC_MAXPATHLEN)
-                    {
-                        strncpy (r, t, tlen + 1);
-                        r += tlen;
-                    }
+                    g_string_append (q, t);
                     p = s;
                     if (*s == '}')
                         p++;
@@ -188,9 +181,7 @@ examine_cd (const char *_path)
 
     g_free (path_tilde);
 
-    *r = '\0';
-
-    return q;
+    return g_string_free (q, FALSE);
 }
 
 /* --------------------------------------------------------------------------------------------- */

+ 10 - 0
tests/src/filemanager/examine_cd.c

@@ -137,6 +137,16 @@ START_TEST (test_examine_cd)
 
     check_examine_cd ("/test/path", "/test/path");
 
+    check_examine_cd ("$AAA", "aaa");
+    check_examine_cd ("${AAA}", "aaa");
+    check_examine_cd ("$AAA/test", "aaa/test");
+    check_examine_cd ("${AAA}/test", "aaa/test");
+
+    check_examine_cd ("/$AAA", "/aaa");
+    check_examine_cd ("/${AAA}", "/aaa");
+    check_examine_cd ("/$AAA/test", "/aaa/test");
+    check_examine_cd ("/${AAA}/test", "/aaa/test");
+
     check_examine_cd ("/test/path/$AAA", "/test/path/aaa");
     check_examine_cd ("/test/path/$AAA/test2", "/test/path/aaa/test2");
     check_examine_cd ("/test/path/test1$AAA/test2", "/test/path/test1aaa/test2");