From 00bce5ad1d5ac92d20617a9eb2647365bf87cab2 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Fri, 9 Oct 2020 16:13:50 +0200 Subject: Splitting preprocessing, Added parsed error helper --- src/preprocess/interpolation.c | 110 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/preprocess/interpolation.c (limited to 'src/preprocess/interpolation.c') diff --git a/src/preprocess/interpolation.c b/src/preprocess/interpolation.c new file mode 100644 index 0000000..8845cb2 --- /dev/null +++ b/src/preprocess/interpolation.c @@ -0,0 +1,110 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* interpolation.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: cacharle +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2020/10/09 15:27:46 by cacharle #+# #+# */ +/* Updated: 2020/10/09 15:32:33 by cacharle ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "eval.h" +#include "lexer.h" +#include "minishell.h" + +static t_tok_lst *st_field_split(char *str) +{ + t_tok_lst *ret; + char *match; + + ret = NULL; + while (*str != '\0') + { + if ((match = ft_strchr(str, ' ')) == NULL) + { + if (tok_lst_push_front(&ret, tok_lst_new(TAG_STR, str)) == NULL) + return (tok_lst_destroy(&ret, free)); + break ; + } + if (tok_lst_push_front(&ret, + tok_lst_new_until(TAG_STR, str, match - str)) == NULL) + return (tok_lst_destroy(&ret, free)); + while (*++match == ' ') + ; + str = match; + if (*str == '\0' && tok_lst_push_front(&ret, + tok_lst_new(TAG_STR, str)) == NULL) + return (tok_lst_destroy(&ret, free)); + } + return ((t_tok_lst *)ft_lstreverse_ret((t_ftlst *)ret)); +} + +size_t interpolate( + char *str, size_t i, t_tok_lst **curr_addr, enum e_tok prev_tag, t_env env) +{ + char *match; + size_t var_len; + t_tok_lst *curr; + char *before; + char *after; + size_t len; + t_tok_lst *fields; + t_tok_lst *last; + t_tok_lst *tmp; + + curr = *curr_addr; + var_len = env_key_len(&str[i + 1], true) + 1; + if ((match = env_search_first_match(env, &str[i + 1])) == NULL) + { + ft_memmove(&str[i], &str[i + var_len], ft_strlen(&str[i + var_len]) + 1); + return (i); + } + str[i] = '\0'; + before = str; + after = &str[i + var_len]; + if (curr->tag & TAG_STR_DOUBLE) + { + curr->content = ft_strjoin3(before, match, after); + free(before); + return (i + ft_strlen(match)); + } + if (curr->tag & TAG_STR) + { + fields = st_field_split(match); + if (fields == NULL) + return (i); + last = tok_lst_last(fields); + len = ft_strlen(last->content); + if (!(prev_tag & TAG_STICK) && *before == '\0' && *fields->content == '\0') + ft_lstpop_front((t_ftlst **)&fields, free); + if (!(curr->tag & TAG_STICK) && *after == '\0' && *last->content == '\0') + ft_lstpop_back((t_ftlst **)&fields, free); + if (fields == NULL) + ; + else if (fields->next == NULL) + { + curr->content = ft_strjoin3(before, fields->content, after); + free(before); + tok_lst_destroy(&fields, free); + return (i + len); + } + else + { + last = tok_lst_last(fields); + last->tag = curr->tag; + curr->tag = TAG_STR; + curr->content = ft_strjoinf_snd(before, fields->content); + last->content = ft_strjoinf_fst(last->content, after); + free(before); + tmp = curr->next; + curr->next = fields->next; + (*curr_addr) = last; + (*curr_addr)->next = tmp; + free(fields); + return (len); + } + } + return (i); +} -- cgit