(examine_cd): refactoring: use GString.

Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
Andrew Borodin 2019-01-12 14:28:35 +03:00
parent f4d448629f
commit aa9d18e3ed
2 changed files with 33 additions and 32 deletions

View File

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

View File

@ -137,6 +137,16 @@ START_TEST (test_examine_cd)
check_examine_cd ("/test/path", "/test/path"); 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", "/test/path/aaa");
check_examine_cd ("/test/path/$AAA/test2", "/test/path/aaa/test2"); check_examine_cd ("/test/path/$AAA/test2", "/test/path/aaa/test2");
check_examine_cd ("/test/path/test1$AAA/test2", "/test/path/test1aaa/test2"); check_examine_cd ("/test/path/test1$AAA/test2", "/test/path/test1aaa/test2");