aboutsummaryrefslogtreecommitdiff
path: root/src/preprocess/interpolation.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/preprocess/interpolation.c')
-rw-r--r--src/preprocess/interpolation.c142
1 files changed, 81 insertions, 61 deletions
diff --git a/src/preprocess/interpolation.c b/src/preprocess/interpolation.c
index 8845cb2..c28d545 100644
--- a/src/preprocess/interpolation.c
+++ b/src/preprocess/interpolation.c
@@ -6,7 +6,7 @@
/* By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/10/09 15:27:46 by cacharle #+# #+# */
-/* Updated: 2020/10/09 15:32:33 by cacharle ### ########.fr */
+/* Updated: 2020/10/10 10:26:43 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -28,83 +28,103 @@ static t_tok_lst *st_field_split(char *str)
return (tok_lst_destroy(&ret, free));
break ;
}
- if (tok_lst_push_front(&ret,
- tok_lst_new_until(TAG_STR, str, match - str)) == NULL)
+ 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)
+ 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)
+#define BEFORE 0
+#define MATCH 1
+#define AFTER 2
+
+static bool st_make_strs(char *strs[3], t_env env, char *str, size_t i)
{
- 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;
+ size_t var_len;
- curr = *curr_addr;
var_len = env_key_len(&str[i + 1], true) + 1;
- if ((match = env_search_first_match(env, &str[i + 1])) == NULL)
+ if ((strs[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);
+ ft_memmove(&str[i], &str[i + var_len],
+ ft_strlen(&str[i + var_len]) + 1);
+ return (false);
}
str[i] = '\0';
- before = str;
- after = &str[i + var_len];
- if (curr->tag & TAG_STR_DOUBLE)
+ strs[BEFORE] = str;
+ strs[AFTER] = &str[i + var_len];
+ return (true);
+}
+
+static size_t st_merge_fields_in_curr(
+ char *strs[3], t_tok_lst **curr, t_tok_lst *fields, size_t len)
+{
+ t_tok_lst *last;
+
+ last = tok_lst_last(fields);
+ last->tag = (*curr)->tag;
+ (*curr)->tag = TAG_STR;
+ (*curr)->content = ft_strjoinf_snd(strs[BEFORE], fields->content);
+ last->content = ft_strjoinf_fst(last->content, strs[AFTER]);
+ free(strs[BEFORE]);
+ last->next = (*curr)->next;
+ (*curr)->next = fields->next;
+ (*curr) = last;
+ free(fields);
+ return (len);
+}
+
+static size_t st_interpolate_non_quoted(
+ char *strs[3], t_tok_lst **curr, size_t i, enum e_tok prev_tag)
+{
+ t_tok_lst *fields;
+ size_t len;
+
+ fields = st_field_split(strs[MATCH]);
+ if (fields == NULL)
+ return (i);
+ len = ft_strlen(tok_lst_last(fields)->content);
+ if (!(prev_tag & TAG_STICK) && *strs[BEFORE] == '\0' &&
+ *fields->content == '\0')
+ ft_lstpop_front((t_ftlst **)&fields, free);
+ if (!((*curr)->tag & TAG_STICK) && *strs[AFTER] == '\0' &&
+ *tok_lst_last(fields)->content == '\0')
+ ft_lstpop_back((t_ftlst **)&fields, free);
+ if (fields != NULL && fields->next == NULL)
{
- curr->content = ft_strjoin3(before, match, after);
- free(before);
- return (i + ft_strlen(match));
+ (*curr)->content =
+ ft_strjoin3(strs[BEFORE], fields->content, strs[AFTER]);
+ free(strs[BEFORE]);
+ tok_lst_destroy(&fields, free);
+ return (i + len);
}
- if (curr->tag & TAG_STR)
+ else if (fields != NULL)
+ return (st_merge_fields_in_curr(strs, curr, fields, len));
+ return (i);
+}
+
+size_t interpolate(
+ void *ptrs[2], size_t i, enum e_tok prev_tag, t_env env)
+{
+ char *strs[3];
+ char *str;
+ t_tok_lst **curr;
+
+ str = ptrs[INTERPOLATION_STR];
+ curr = ptrs[INTERPOLATION_CURR];
+ if (!st_make_strs(strs, env, str, i))
+ return (i);
+ if ((*curr)->tag & TAG_STR_DOUBLE)
{
- 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);
- }
+ (*curr)->content = ft_strjoin3(strs[BEFORE], strs[MATCH], strs[AFTER]);
+ free(strs[BEFORE]);
+ return (i + ft_strlen(strs[MATCH]));
}
- return (i);
+ return (st_interpolate_non_quoted(strs, curr, i, prev_tag));
}