aboutsummaryrefslogtreecommitdiff
path: root/src/preprocess/interpolation.c
diff options
context:
space:
mode:
authorCharles Cabergs <me@cacharle.xyz>2020-10-09 16:13:50 +0200
committerCharles Cabergs <me@cacharle.xyz>2020-10-09 16:13:50 +0200
commit00bce5ad1d5ac92d20617a9eb2647365bf87cab2 (patch)
treeaaad5cbb6cdb6372f5809d50cdc65b912695956f /src/preprocess/interpolation.c
parente8075fcf93873149593ccd141f99d65a4db40f4f (diff)
downloadminishell-00bce5ad1d5ac92d20617a9eb2647365bf87cab2.tar.gz
minishell-00bce5ad1d5ac92d20617a9eb2647365bf87cab2.tar.bz2
minishell-00bce5ad1d5ac92d20617a9eb2647365bf87cab2.zip
Splitting preprocessing, Added parsed error helper
Diffstat (limited to 'src/preprocess/interpolation.c')
-rw-r--r--src/preprocess/interpolation.c110
1 files changed, 110 insertions, 0 deletions
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 <me@cacharle.xyz> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* 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);
+}