From 5b681182824ae45b5a27d1503de32fa2760c5800 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Sat, 10 Oct 2020 10:34:20 +0200 Subject: Norming interpolation --- src/main.c | 4 +- src/parser/expr.c | 8 +-- src/parser/parsed_error.c | 4 +- src/parser/parser.c | 12 ++-- src/preprocess/interpolation.c | 142 +++++++++++++++++++++++------------------ src/preprocess/preprocess.c | 8 +-- 6 files changed, 99 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index 28496b4..9c9383a 100644 --- a/src/main.c +++ b/src/main.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/02/28 11:45:44 by cacharle #+# #+# */ -/* Updated: 2020/10/10 08:39:05 by cacharle ### ########.fr */ +/* Updated: 2020/10/10 09:25:52 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,7 +53,7 @@ int execute(t_env env, char *input) return (status); } parser_out = parse(lexer_out); - if (parser_out == NULL || parser_out->syntax_error) + if (parsed_check(parser_out)) { free(parser_out); return (2); diff --git a/src/parser/expr.c b/src/parser/expr.c index 04aa685..f4c82ce 100644 --- a/src/parser/expr.c +++ b/src/parser/expr.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/10/10 08:42:24 by cacharle #+# #+# */ -/* Updated: 2020/10/10 09:11:10 by cacharle ### ########.fr */ +/* Updated: 2020/10/10 09:24:33 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,7 +53,7 @@ static t_parsed *st_parse_cmd_body(t_tok_lst *input) else if (input->tag & TAG_IS_REDIR) { tmp = parse_redir(input, &ast->redirs); - if (parsed_err(tmp)) + if (parsed_check(tmp)) { tok_lst_destroy(&tmp->rest, free); ast_destroy(ast); @@ -86,7 +86,7 @@ static t_parsed *st_parse_parenthesis(t_tok_lst *input) t_parsed *tmp; t_ast *ast; - if (parsed_err(parsed = parse_op(input))) + if (parsed_check(parsed = parse_op(input))) return (parsed); if ((input = parsed->rest) == NULL || !(input->tag & TAG_PARENT_CLOSE)) { @@ -100,7 +100,7 @@ static t_parsed *st_parse_parenthesis(t_tok_lst *input) parsed->ast = ast; while (input != NULL && input->tag & TAG_IS_REDIR) { - if (parsed_err(tmp = parse_redir(input, &parsed->ast->redirs))) + if (parsed_check(tmp = parse_redir(input, &parsed->ast->redirs))) return (tmp); input = tmp->rest; free(tmp); diff --git a/src/parser/parsed_error.c b/src/parser/parsed_error.c index a38a85c..3486235 100644 --- a/src/parser/parsed_error.c +++ b/src/parser/parsed_error.c @@ -6,7 +6,7 @@ /* By: cacharle +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/10/10 09:20:17 by cacharle #+# #+# */ -/* Updated: 2020/10/10 09:20:30 by cacharle ### ########.fr */ +/* Updated: 2020/10/10 09:24:59 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,7 +37,7 @@ t_parsed *parsed_unexpected(char *content) return (parsed_error("syntax error near unexpected token `%s'", content)); } -bool parsed_err(t_parsed *parsed) +bool parsed_check(t_parsed *parsed) { return (parsed == NULL || parsed->syntax_error); } diff --git a/src/parser/parser.c b/src/parser/parser.c index a75ad03..85e2214 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -6,7 +6,7 @@ /* By: nahaddac +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2020/06/17 18:09:04 by nahaddac #+# #+# */ -/* Updated: 2020/10/10 09:19:32 by cacharle ### ########.fr */ +/* Updated: 2020/10/10 09:24:28 by cacharle ### ########.fr */ /* */ /* ************************************************************************** */ @@ -44,12 +44,12 @@ t_parsed *parse_pipeline(t_tok_lst *input) t_ast *pipeline_ast; expr = parse_expr(input); - if (parsed_err(expr) || expr->rest == NULL || expr->rest->tag != TAG_PIPE) + if (parsed_check(expr) || expr->rest == NULL || expr->rest->tag != TAG_PIPE) return (expr); tok_lst_pop_front(&expr->rest, free); if (expr->rest == NULL) return (destroy_ret(expr, parsed_expected())); - if (parsed_err(tail = parse_pipeline(expr->rest))) + if (parsed_check(tail = parse_pipeline(expr->rest))) return (destroy_ret(expr, tail)); expr_ast = expr->ast; free(expr); @@ -91,7 +91,7 @@ t_parsed *parse_op(t_tok_lst *input) if (input == NULL) return (NULL); - if (parsed_err(left = parse_pipeline(input))) + if (parsed_check(left = parse_pipeline(input))) return (left); if ((input = left->rest) == NULL || input->tag & TAG_PARENT_CLOSE) return (left); @@ -107,7 +107,7 @@ t_parsed *parse_op(t_tok_lst *input) if (input == NULL) return (destroy_ret(left, parsed_expected())); right = parse_op(input); - if (parsed_err(right)) + if (parsed_check(right)) return (destroy_ret(left, right)); return (parse_op_build(left, right, sep_tag)); } @@ -120,7 +120,7 @@ t_parsed *parse(t_tok_lst *input) if (input == NULL) return (NULL); parsed = parse_op(input); - if (parsed_err(parsed)) + if (parsed_check(parsed)) return (parsed); if (parsed->rest != NULL) { 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 +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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 +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* 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; -- cgit