diff options
| author | Charles <sircharlesaze@gmail.com> | 2020-06-09 17:09:55 +0200 |
|---|---|---|
| committer | Charles <sircharlesaze@gmail.com> | 2020-06-09 17:09:55 +0200 |
| commit | 5ade92701836ce5ee1d39fc8d486b7709547058e (patch) | |
| tree | fbcde5c25c995f7a71cc7f36d86170a53b53a472 /src/preprocess.c | |
| parent | 82f1e954590de21f6db9b1b6e3dba78a951bc319 (diff) | |
| download | minishell-5ade92701836ce5ee1d39fc8d486b7709547058e.tar.gz minishell-5ade92701836ce5ee1d39fc8d486b7709547058e.tar.bz2 minishell-5ade92701836ce5ee1d39fc8d486b7709547058e.zip | |
Added iterpolation like bash according to lexer output (2 leaks)
Diffstat (limited to 'src/preprocess.c')
| -rw-r--r-- | src/preprocess.c | 96 |
1 files changed, 77 insertions, 19 deletions
diff --git a/src/preprocess.c b/src/preprocess.c index c30bb70..0d72a2c 100644 --- a/src/preprocess.c +++ b/src/preprocess.c @@ -6,12 +6,13 @@ /* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/04/05 15:04:06 by charles ### ########.fr */ +/* Updated: 2020/06/09 17:03:37 by charles ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" #include "ms_glob.h" +#include "lexer.h" static char *iterpolate(char *str, t_env env) { @@ -28,11 +29,18 @@ static char *iterpolate(char *str, t_env env) if (dstr->str[i] == '$') { if ((match = env_search_first_match(env, dstr->str + i + 1)) == NULL) + { ft_dstrerase(dstr, i, utils_var_end(dstr->str + i + 1)); + i--; + } else { if (ft_dstrsubstitute(dstr, match, i, utils_var_end(dstr->str + i + 1)) == NULL) + { + ft_dstrdestroy(dstr); return (NULL); + } + i += ft_strlen(match) - 1; } } i++; @@ -40,30 +48,80 @@ static char *iterpolate(char *str, t_env env) return (ft_dstrunwrap(dstr)); } -static char *preprocess_arg(char *arg, t_env env) +static char *iterpolate_globs(char *str) +{ + char **strs; + int i; + + if ((strs = ft_split(str, ' ')) == NULL) + return (NULL); + i = 0; + while (strs[i] != NULL) + { + if (ft_strchr(strs[i], '*') != NULL + && (strs[i] = ms_glob(strs[i])) == NULL) + { + ft_split_destroy(strs); + return (NULL); + } + i++; + } + return (ft_strsjoinf(strs, " ")); +} + +static int splat_arg(t_ftvec *argv, int i) { - if (*arg == '\'') - return (ft_strsubf(arg, 1, ft_strlen(arg) - 1)); - if (*arg == '"') + t_token *splated; + char **strs; + int j; + + if ((splated = ft_vectake(argv, i)) == NULL + || (strs = ft_split(splated->content, ' ')) == NULL) + return (-1); + j = 0; + while (strs[j] != NULL) { - if (ft_strchr(arg, '$') != NULL) - arg = iterpolate(arg, env); - return (ft_strsubf(arg, 1, ft_strlen(arg) - 1)); + if (ft_vecinsert_safe(argv, i + j, token_new(LTAG_STR, strs[j])) == NULL) + { + ft_split_destroy(strs); + return (-1); + } + j++; } - if (ft_strchr(arg, '$') != NULL) - return (iterpolate(arg, env)); - if (ft_strchr(arg, '*') != NULL) - return (ms_glob(arg)); - return (arg); + ft_split_destroy(strs); + return i + j - 1; } -char **preprocess_argv(char **argv, t_env env) +void iter_func_unwrap_token(void **addr) { - int i; + char *content; + + content = (*(t_token**)addr)->content; + free(*(t_token**)addr); + *(char**)addr = content; +} + +char **preprocess_argv(t_ftvec *argv, t_env env) +{ + size_t i; + t_token *token; i = -1; - while (argv[++i] != NULL) - if ((argv[i] = preprocess_arg(argv[i], env)) == NULL) - return (NULL); - return (argv); + while (++i < argv->size) + { + token = argv->data[i]; + if (token->tag == LTAG_STR_SINGLE) + continue ; + token->content = iterpolate(token->content, env); + if (token->tag == LTAG_STR) + { + if (ft_strchr(token->content, '*') != NULL) + token->content = iterpolate_globs(token->content); + if ((i = splat_arg(argv, i)) == (size_t)-1) + return (NULL); + } + } + ft_veciter_addr(argv, iter_func_unwrap_token); + ft_vecpush(argv, NULL); + return ((char**)ft_vecunwrap(argv)); } |
