Ejemplo n.º 1
0
static void test_expand_tilde_home(void)
{
    char *dir;
    const char *home = util_get_home_dir();

    check_expand("~", "~");
    check_expand("~/", home);
    check_expand("foo~/bar", "foo~/bar");
    check_expand("~/foo", (dir = g_strdup_printf("%s/foo", home)));
    g_free(dir);

    check_expand("foo ~/bar", (dir = g_strdup_printf("foo %s/bar", home)));
    g_free(dir);

    check_expand("~/~", (dir = g_strdup_printf("%s/~", home)));
    g_free(dir);

    check_expand("~/~/", (dir = g_strdup_printf("%s/~/", home)));
    g_free(dir);
}
Ejemplo n.º 2
0
static void test_expand_tilde_user(void)
{
    const char *home = util_get_home_dir();
    const char *user = g_get_user_name();
    char *in, *out;

    /* don't expand within words */
    in = g_strdup_printf("foo~%s/bar", user);
    check_expand(in, in);
    g_free(in);

    check_expand((in = g_strdup_printf("foo ~%s", user)), (out = g_strdup_printf("foo %s", home)));
    g_free(in);
    g_free(out);

    check_expand((in = g_strdup_printf("~%s", user)), home);
    g_free(in);

    check_expand((in = g_strdup_printf("~%s/bar", user)), (out = g_strdup_printf("%s/bar", home)));
    g_free(in);
    g_free(out);
}
Ejemplo n.º 3
0
Archivo: util.c Proyecto: hirkmt/vimb
/**
 * Reads given input and try to parse ~/, ~user, $VAR or ${VAR} expansion
 * from the start of the input and moves the input pointer to the first
 * not expanded char. If no expansion pattern was found, the first char is
 * appended to given GString.
 *
 * @input:    String pointer with the content to be parsed.
 * @str:      GString that will be filled with expanded content.
 * @flags     Flags that determine which expansion are processed.
 * @quoteable String of chars that are additionally escapable by \.
 * Returns true if input started with expandable pattern.
 */
gboolean util_parse_expansion(const char **input, GString *str, int flags,
    const char *quoteable)
{
    GString *name;
    const char *env, *prev, quote = '\\';
    struct passwd *pwd;
    gboolean expanded = false;

    prev = *input;
    if (flags & UTIL_EXP_TILDE && **input == '~') {
        /* skip ~ */
        (*input)++;

        if (**input == '/') {
            g_string_append(str, util_get_home_dir());
            expanded = true;
            /* if there is no char or space after ~/ skip the / to get
             * /home/user instead of /home/user/ */
            if (!*(*input + 1) || VB_IS_SPACE(*(*input + 1))) {
                (*input)++;
            }
        } else {
            /* look ahead to / space or end of string to get a possible
             * username for ~user pattern */
            name = g_string_new("");
            /* current char is ~ that is skipped to get the user name */
            while (VB_IS_IDENT(**input)) {
                g_string_append_c(name, **input);
                (*input)++;
            }
            /* append the name to the destination string */
            if ((pwd = getpwnam(name->str))) {
                g_string_append(str, pwd->pw_dir);
                expanded = true;
            }
            g_string_free(name, true);
        }
        /* move pointer back to last expanded char */
        (*input)--;
    } else if (flags & UTIL_EXP_DOLLAR && **input == '$') {
        /* skip the $ */
        (*input)++;

        name = g_string_new("");
        /* look for ${VAR}*/
        if (**input == '{') {
            /* skip { */
            (*input)++;

            /* look ahead to } or end of string */
            while (**input && **input != '}') {
                g_string_append_c(name, **input);
                (*input)++;
            }
            /* if the } was reached - skip this */
            if (**input == '}') {
                (*input)++;
            }
        } else { /* process $VAR */
            /* look ahead to /, space or end of string */
            while (VB_IS_IDENT(**input)) {
                g_string_append_c(name, **input);
                (*input)++;
            }
        }
        /* append the variable to the destination string */
        if ((env = g_getenv(name->str))) {
            g_string_append(str, env);
        }
        /* move pointer back to last expanded char */
        (*input)--;
        /* variable are expanded even if they do not exists */
        expanded = true;
        g_string_free(name, true);
    } else if (flags & UTIL_EXP_SPECIAL && **input == '%') {
        if (*vb.state.uri) {
            /* TODO check for modifiers like :h:t:r:e */
            g_string_append(str, vb.state.uri);
            expanded = true;
        }
    }

    if (!expanded) {
        /* restore the pointer position if no expansion was found */
        *input = prev;

        /* handle escaping of quoteable chars */
        if (**input == quote) {
            /* move pointer to the next char */
            (*input)++;
            if (!**input) {
                /* if input ends here - use only the quote char */
                g_string_append_c(str, quote);
                (*input)--;
            } else if (strchr(quoteable, **input)
                || (flags & UTIL_EXP_TILDE && **input == '~')
                || (flags & UTIL_EXP_DOLLAR && **input == '$')
                || (flags & UTIL_EXP_SPECIAL && **input == '%')
            ) {
                /* escaped char becomes only char */
                g_string_append_c(str, **input);
            } else {
                /* put escape char and next char into the result string */
                g_string_append_c(str, quote);
                g_string_append_c(str, **input);
            }
        } else {
            /* take the char like it is */
            g_string_append_c(str, **input);
        }
    }

    return expanded;
}