aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/minishell.h7
-rw-r--r--include/parser.h4
-rw-r--r--src/main.c4
-rw-r--r--src/parser/expr.c8
-rw-r--r--src/parser/parsed_error.c4
-rw-r--r--src/parser/parser.c12
-rw-r--r--src/preprocess/interpolation.c142
-rw-r--r--src/preprocess/preprocess.c8
8 files changed, 106 insertions, 83 deletions
diff --git a/include/minishell.h b/include/minishell.h
index b1af152..04a9ce0 100644
--- a/include/minishell.h
+++ b/include/minishell.h
@@ -6,7 +6,7 @@
/* By: cacharle <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/26 15:33:51 by cacharle #+# #+# */
-/* Updated: 2020/10/10 08:14:38 by cacharle ### ########.fr */
+/* Updated: 2020/10/10 10:33:56 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -123,11 +123,14 @@ int builtin_exit(char **argv, t_env env);
** preprocess.c
*/
+# define INTERPOLATION_STR 0
+# define INTERPOLATION_CURR 1
+
char **preprocess(t_tok_lst **tokens, t_env env);
int preprocess_filename(
t_tok_lst **tokens, t_env env, char **filename);
size_t interpolate(
- char *str, size_t i, t_tok_lst **curr_addr,
+ void *ptrs[2], size_t i,
enum e_tok prev_tag, t_env env);
/*
diff --git a/include/parser.h b/include/parser.h
index c2d2381..91acfe7 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -6,7 +6,7 @@
/* By: cacharle <cacharle@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/28 09:00:00 by cacharle #+# #+# */
-/* Updated: 2020/10/10 09:20:53 by cacharle ### ########.fr */
+/* Updated: 2020/10/10 09:24:15 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -119,7 +119,7 @@ void parsed_destroy(t_parsed *parsed);
t_parsed *parsed_error(const char *format, ...);
t_parsed *parsed_expected(void);
t_parsed *parsed_unexpected(char *content);
-bool parsed_err(t_parsed *parsed);
+bool parsed_check(t_parsed *parsed);
/*
** parse.c
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 <cacharle@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <nahaddac@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* 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 <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;