diff options
Diffstat (limited to 'src/preprocess')
| -rw-r--r-- | src/preprocess/interpolation.c | 142 | ||||
| -rw-r--r-- | src/preprocess/preprocess.c | 8 |
2 files changed, 85 insertions, 65 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)); } diff --git a/src/preprocess/preprocess.c b/src/preprocess/preprocess.c index 03ae203..3852b8b 100644 --- a/src/preprocess/preprocess.c +++ b/src/preprocess/preprocess.c @@ -6,7 +6,7 @@ /* By: charles <charles@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/04/03 08:58:49 by charles #+# #+# */ -/* Updated: 2020/10/09 15:31:33 by cacharle ### ########.fr */ +/* Updated: 2020/10/10 10:32:53 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -79,15 +79,15 @@ char **preprocess(t_tok_lst **tokens, t_env env) curr = *tokens; while (curr != NULL) { - if (curr->tag & (TAG_STR | TAG_STR_DOUBLE)) + if (curr->tag & (TAG_STR | TAG_STR_DOUBLE) && (i = -1)) { - i = -1; while ((str = curr->content) != NULL && str[++i] != '\0') { if (escape(str + i, curr->tag)) continue; if (str[i] == '$') - i = interpolate(str, i, &curr, prev_tag, env) - 1; + i = interpolate((void*[2]){str, &curr}, + i, prev_tag, env) - 1; } } prev_tag = curr->tag; |
