aboutsummaryrefslogtreecommitdiff
path: root/src
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
parente8075fcf93873149593ccd141f99d65a4db40f4f (diff)
downloadminishell-00bce5ad1d5ac92d20617a9eb2647365bf87cab2.tar.gz
minishell-00bce5ad1d5ac92d20617a9eb2647365bf87cab2.tar.bz2
minishell-00bce5ad1d5ac92d20617a9eb2647365bf87cab2.zip
Splitting preprocessing, Added parsed error helper
Diffstat (limited to 'src')
-rw-r--r--src/eval/eval.c4
-rw-r--r--src/eval/operation.c4
-rw-r--r--src/lexer/lexer.c12
-rw-r--r--src/lexer/tok_lst.c16
-rw-r--r--src/lexer/trim.c6
-rw-r--r--src/lexer/utils.c26
-rw-r--r--src/main.c34
-rw-r--r--src/parser/parsed.c18
-rw-r--r--src/parser/parser.c42
-rw-r--r--src/preprocess.c215
-rw-r--r--src/preprocess/filename.c35
-rw-r--r--src/preprocess/interpolation.c110
-rw-r--r--src/preprocess/preprocess.c98
13 files changed, 332 insertions, 288 deletions
diff --git a/src/eval/eval.c b/src/eval/eval.c
index 0df8b85..032fc30 100644
--- a/src/eval/eval.c
+++ b/src/eval/eval.c
@@ -6,7 +6,7 @@
/* By: charles <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/09/13 20:38:06 by charles #+# #+# */
-/* Updated: 2020/10/09 14:03:31 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 16:12:27 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -64,7 +64,7 @@ int eval(int fds[2], t_env env, t_ast *ast)
if (ast->tag == AST_CMD)
return (eval_cmd(fds, env, ast));
if (ast->tag == AST_PIPELINE)
- return (eval_pipeline(fds, env, ast));
+ return (eval_pipeline(env, ast));
if (ast->tag == AST_PARENT)
return (eval_parenthesis(fds, env, ast));
return (EVAL_FATAL);
diff --git a/src/eval/operation.c b/src/eval/operation.c
index 19ecec7..f1daa0b 100644
--- a/src/eval/operation.c
+++ b/src/eval/operation.c
@@ -6,7 +6,7 @@
/* By: charles <charles.cabergs@gmail.com> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/06/17 15:27:22 by charles #+# #+# */
-/* Updated: 2020/10/09 14:54:43 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 16:12:14 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -62,7 +62,7 @@ static int st_run_piped(
return (pid);
}
-int eval_pipeline(int fds[2], t_env env, t_ast *ast)
+int eval_pipeline(t_env env, t_ast *ast)
{
t_ftlst *curr;
int pipes[3];
diff --git a/src/lexer/lexer.c b/src/lexer/lexer.c
index 9b947f4..5df63ba 100644
--- a/src/lexer/lexer.c
+++ b/src/lexer/lexer.c
@@ -6,15 +6,14 @@
/* By: nahaddac <nahaddac@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/07/16 08:18:25 by nahaddac #+# #+# */
-/* Updated: 2020/10/09 12:29:32 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 15:12:51 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
#include "lexer.h"
#include <stdio.h>
-// len until meaningful character for non quoted str
-int len_until_sep(char *input)
+int len_until_sep(char *input)
{
int i;
@@ -40,7 +39,6 @@ int len_until_sep(char *input)
return (i);
}
-// token content length
int tok_len(char *input)
{
int i;
@@ -74,10 +72,10 @@ int tok_len(char *input)
** return all token
*/
-t_tok_lst *create_token_list(char *input, t_tok_lst **lst)
+t_tok_lst *create_token_list(char *input, t_tok_lst **lst)
{
t_tok_lst *tok;
- size_t i;
+ size_t i;
size_t j;
size_t len;
@@ -105,7 +103,7 @@ t_tok_lst *create_token_list(char *input, t_tok_lst **lst)
** \return The created tokens or NULL on error
*/
-int lexer(char *input, t_tok_lst **out)
+int lexer(char *input, t_tok_lst **out)
{
int status;
diff --git a/src/lexer/tok_lst.c b/src/lexer/tok_lst.c
index 9ae0ce1..89ab120 100644
--- a/src/lexer/tok_lst.c
+++ b/src/lexer/tok_lst.c
@@ -6,7 +6,7 @@
/* By: charles <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/08/27 09:32:58 by charles #+# #+# */
-/* Updated: 2020/10/08 17:38:59 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 15:14:38 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -14,7 +14,8 @@
t_tok_lst *tok_lst_new(enum e_tok tag, char *content)
{
- return (tok_lst_new_until(tag, content, content == NULL ? 0 : ft_strlen(content)));
+ return (tok_lst_new_until(
+ tag, content, content == NULL ? 0 : ft_strlen(content)));
}
/*
@@ -25,14 +26,15 @@ t_tok_lst *tok_lst_new(enum e_tok tag, char *content)
** \return An allocated tok_lst or NULL on error
*/
-t_tok_lst *tok_lst_new_until(enum e_tok tag, char *content, size_t n)
+t_tok_lst *tok_lst_new_until(
+ enum e_tok tag, char *content, size_t n)
{
t_tok_lst *ret;
if ((ret = malloc(sizeof(t_tok_lst))) == NULL)
return (NULL);
if (content == NULL)
- ret->content = NULL;
+ ret->content = NULL;
else if ((ret->content = ft_strndup(content, n)) == NULL)
{
free(ret);
@@ -48,7 +50,8 @@ void tok_lst_push_back(t_tok_lst **tokens, t_tok_lst *pushed)
ft_lstpush_back((t_ftlst**)tokens, (t_ftlst*)pushed);
}
-t_tok_lst *tok_lst_push_front(t_tok_lst **tokens, t_tok_lst *pushed)
+t_tok_lst *tok_lst_push_front(
+ t_tok_lst **tokens, t_tok_lst *pushed)
{
if (pushed == NULL)
return (NULL);
@@ -56,7 +59,8 @@ t_tok_lst *tok_lst_push_front(t_tok_lst **tokens, t_tok_lst *pushed)
return (*tokens);
}
-void tok_lst_pop_front(t_tok_lst **tokens, void (*del)(void*))
+void tok_lst_pop_front(
+ t_tok_lst **tokens, void (*del)(void*))
{
ft_lstpop_front((t_ftlst**)tokens, del);
}
diff --git a/src/lexer/trim.c b/src/lexer/trim.c
index 0f3279b..d0ba90a 100644
--- a/src/lexer/trim.c
+++ b/src/lexer/trim.c
@@ -6,13 +6,11 @@
/* By: nahaddac <nahaddac@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/07/16 08:18:36 by nahaddac #+# #+# */
-/* Updated: 2020/10/07 10:36:41 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 15:17:45 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
-
#include "lexer.h"
-#include <stdio.h>
void del_space(char *str)
{
@@ -32,7 +30,7 @@ void del_space(char *str)
}
}
-int del_quote(char *str)
+int del_quote(char *str)
{
size_t i;
size_t quote_counter;
diff --git a/src/lexer/utils.c b/src/lexer/utils.c
index 0b7baa3..624b460 100644
--- a/src/lexer/utils.c
+++ b/src/lexer/utils.c
@@ -6,14 +6,13 @@
/* By: nahaddac <nahaddac@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/07/16 08:18:15 by nahaddac #+# #+# */
-/* Updated: 2020/10/08 14:11:51 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 15:24:31 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
#include "lexer.h"
-// return token tag corresponding to string id
-enum e_tok tok_assign_tag(char *content)
+enum e_tok tok_assign_tag(char *content)
{
if (content[0] == ';')
return (TAG_END);
@@ -21,7 +20,7 @@ enum e_tok tok_assign_tag(char *content)
return (TAG_AND);
if (ft_strncmp(content, "||", 2) == 0)
return (TAG_OR);
- if(content[0] == '|')
+ if (content[0] == '|')
return (TAG_PIPE);
if (content[0] == '>')
return (TAG_REDIR_OUT);
@@ -42,14 +41,13 @@ enum e_tok tok_assign_tag(char *content)
** a la fin (char *)tk->tok ne figure pas d'espace.
*/
-enum e_tok tok_assign_stick(t_tok_lst *tok)
+enum e_tok tok_assign_stick(t_tok_lst *tok)
{
int i;
i = ft_strlen(tok->content);
- if (i > 0)
- if (ft_isblank(tok->content[i - 1]))
- return (tok->tag);
+ if (i > 0 && ft_isblank(tok->content[i - 1]))
+ return (tok->tag);
return (tok->tag | TAG_STICK);
}
@@ -58,7 +56,8 @@ enum e_tok tok_assign_stick(t_tok_lst *tok)
** la chaine de character est un str où '' où ''
** \note the loop after ft_strpbrk is to search again if the quote was escaped
*/
-enum e_tok tok_assign_str(t_tok_lst *tok)
+
+enum e_tok tok_assign_str(t_tok_lst *tok)
{
char *found;
@@ -74,20 +73,17 @@ enum e_tok tok_assign_str(t_tok_lst *tok)
return (tok_assign_stick(tok));
}
-
-// check is char is separator
-int lexer_sep(char c)
+int lexer_sep(char c)
{
return (ft_strchr(";&|><()", c) != NULL);
}
-// number of starting space character
-int lexer_space(char *input)
+int lexer_space(char *input)
{
return (ft_strspn(input, " \t"));
}
-int quote_len(char *input, int i)
+int quote_len(char *input, int i)
{
char quote_type;
diff --git a/src/main.c b/src/main.c
index baa03b5..28b808a 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/09 13:57:22 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 15:51:00 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -25,12 +25,27 @@ int debug_parser(char *input);
t_state g_state;
+int run_eval(t_env env, t_parsed *parser_out)
+{
+ int status;
+ int fds[2];
+
+ fds[0] = FD_NONE;
+ fds[1] = FD_NONE;
+ status = eval(fds, env, parser_out->ast);
+ ast_destroy(parser_out->ast);
+ free(parser_out);
+ if (status == EVAL_FATAL)
+ exit(1);
+ g_state.last_status = status;
+ return (status);
+}
+
int execute(t_env env, char *input)
{
t_tok_lst *lexer_out;
int status;
t_parsed *parser_out;
- int fds[2];
if (utils_strisblank(input))
return (0);
@@ -46,15 +61,7 @@ int execute(t_env env, char *input)
free(parser_out);
return (2);
}
- fds[0] = FD_NONE;
- fds[1] = FD_NONE;
- status = eval(fds, env, parser_out->ast);
- ast_destroy(parser_out->ast);
- free(parser_out);
- if (status == EVAL_FATAL)
- exit(1);
- g_state.last_status = status;
- return (status);
+ return (run_eval(env, parser_out));
}
int repl(t_env env)
@@ -65,11 +72,6 @@ int repl(t_env env)
print_prompt();
while ((ret = ft_getline(STDIN_FILENO, &line)) == FTGL_OK)
{
- if (*line == '\0')
- {
- print_prompt();
- continue ;
- }
g_state.killed = false;
if (execute(env, line) == EVAL_FATAL)
return (2);
diff --git a/src/parser/parsed.c b/src/parser/parsed.c
index a2b569a..7b82832 100644
--- a/src/parser/parsed.c
+++ b/src/parser/parsed.c
@@ -6,7 +6,7 @@
/* By: charles <me@cacharle.xyz> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/08/27 20:27:42 by charles #+# #+# */
-/* Updated: 2020/10/09 14:08:46 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 16:00:02 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -38,3 +38,19 @@ t_parsed *parsed_error(const char *format, ...)
ft_putchar_fd('\n', STDERR_FILENO);
return (err);
}
+
+t_parsed *parsed_expected(void)
+{
+ return (parsed_error("syntax error expected token"));
+}
+
+t_parsed *parsed_unexpected(char *content)
+{
+ return (parsed_error("syntax error near unexpected token `%s'", content));
+}
+
+void parsed_destroy(t_parsed *parsed)
+{
+ ast_destroy(parsed->ast);
+ free(parsed);
+}
diff --git a/src/parser/parser.c b/src/parser/parser.c
index 8d5a0aa..be71097 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/09 14:30:29 by cacharle ### ########.fr */
+/* Updated: 2020/10/09 16:10:31 by cacharle ### ########.fr */
/* */
/* ************************************************************************** */
@@ -20,12 +20,12 @@
static char *g_sep_str_lookup[] = {
[TAG_END] = ";",
- [TAG_AND] = "&&",
[TAG_OR] = "||",
- [TAG_PIPE] = "|",
[TAG_REDIR_IN] = "<",
[TAG_REDIR_APPEND] = ">>",
[TAG_PARENT_CLOSE] = ")",
+ [TAG_AND] = "&&",
+ [TAG_PIPE] = "|",
[TAG_REDIR_OUT] = ">",
[TAG_PARENT_OPEN] = "(",
};
@@ -38,17 +38,18 @@ static char *g_sep_str_lookup[] = {
t_parsed *parse_redir(t_tok_lst *input, t_tok_lst **redirs)
{
- t_parsed *ret;
+ t_parsed *ret;
tok_lst_push_back(redirs, tok_lst_uncons(&input));
- while (input != NULL && input->tag & TAG_IS_STR && input->tag & TAG_STICK &&
+ while (input != NULL && input->tag & TAG_IS_STR &&
+ input->tag & TAG_STICK &&
input->next != NULL && input->next->tag & TAG_IS_STR)
tok_lst_push_back(redirs, tok_lst_uncons(&input));
if (input == NULL)
- return (parsed_error("syntax error near unexpected token `newline'"));
+ return (parsed_unexpected("newline"));
if (!(input->tag & TAG_IS_STR))
{
- ret = parsed_error("syntax error near unexpected token `%s'", input->content);
+ ret = parsed_unexpected(input->content);
tok_lst_destroy(&input, free);
return (ret);
}
@@ -60,12 +61,14 @@ t_parsed *parse_cmd(t_tok_lst *input)
{
t_ast *ast;
t_parsed *tmp;
+ t_parsed *ret;
- if (input->tag & TAG_IS_SEP || input->tag == TAG_PIPE || input->tag == TAG_PARENT_CLOSE)
+ if (input->tag & TAG_IS_SEP || input->tag == TAG_PIPE ||
+ input->tag == TAG_PARENT_CLOSE)
{
- tmp = parsed_error("syntax error near unexpected token `%s'", input->content);
+ ret = parsed_unexpected(input->content);
tok_lst_destroy(&input, free);
- return (tmp);
+ return (ret);
}
if ((ast = ast_new(AST_CMD)) == NULL)
return (NULL);
@@ -99,14 +102,15 @@ t_parsed *parse_pipeline(t_tok_lst *input)
t_ast *pipeline_ast;
expr = parse_expr(input);
- if (expr == NULL || expr->syntax_error || expr->rest == NULL || expr->rest->tag != TAG_PIPE)
+ if (expr == NULL || expr->syntax_error ||
+ expr->rest == NULL || expr->rest->tag != TAG_PIPE)
return (expr);
tok_lst_pop_front(&expr->rest, free);
if (expr->rest == NULL)
{
ast_destroy(expr->ast);
free(expr);
- return (parsed_error("syntax error expected token"));
+ return (parsed_expected());
}
tail = parse_pipeline(expr->rest);
if (tail == NULL || tail->syntax_error)
@@ -154,8 +158,7 @@ t_parsed *parse_op(t_tok_lst *input)
ast_destroy(left->ast);
tok_lst_destroy(&left->rest, free);
free(left);
- return (parsed_error(
- "syntax error near unexpected token `%s'", g_sep_str_lookup[sep_tag]));
+ return (parsed_unexpected(g_sep_str_lookup[sep_tag]));
}
tok_lst_pop_front(&input, free);
if (input == NULL && sep_tag == TAG_END)
@@ -167,7 +170,7 @@ t_parsed *parse_op(t_tok_lst *input)
{
ast_destroy(left->ast);
free(left);
- return (parsed_error("syntax error expected token"));
+ return (parsed_expected());
}
right = parse_op(input);
if (right == NULL || right->syntax_error)
@@ -202,7 +205,7 @@ t_parsed *parse_expr(t_tok_lst *input)
{
tok_lst_pop_front(&input, free);
if (input == NULL)
- return (parsed_error("syntax error expected token"));
+ return (parsed_expected());
parsed = parse_op(input);
if (parsed == NULL || parsed->syntax_error)
return (parsed);
@@ -211,7 +214,7 @@ t_parsed *parse_expr(t_tok_lst *input)
{
ast_destroy(parsed->ast);
free(parsed);
- return (parsed_error("syntax error expected token"));
+ return (parsed_expected());
}
tok_lst_pop_front(&input, free);
if ((ast = ast_new(AST_PARENT)) == NULL)
@@ -223,8 +226,8 @@ t_parsed *parse_expr(t_tok_lst *input)
tmp = parse_redir(input, &parsed->ast->redirs);
if (tmp == NULL || tmp->syntax_error)
return (tmp);
- input = tmp->rest;
free(tmp);
+ input = tmp->rest;
}
parsed->rest = input;
return (parsed);
@@ -244,8 +247,7 @@ t_parsed *parse(t_tok_lst *input)
return (parsed);
if (parsed->rest != NULL)
{
- ret = parsed_error(
- "syntax error near unexpected token `%s'", parsed->rest->content);
+ ret = parsed_unexpected(parsed->rest->content);
tok_lst_destroy(&parsed->rest, free);
ast_destroy(parsed->ast);
free(parsed);
diff --git a/src/preprocess.c b/src/preprocess.c
deleted file mode 100644
index 7f37a97..0000000
--- a/src/preprocess.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* ************************************************************************** */
-/* */
-/* ::: :::::::: */
-/* preprocess.c :+: :+: :+: */
-/* +:+ +:+ +:+ */
-/* By: charles <charles@student.42.fr> +#+ +:+ +#+ */
-/* +#+#+#+#+#+ +#+ */
-/* Created: 2020/04/03 08:58:49 by charles #+# #+# */
-/* Updated: 2020/10/08 09:58:48 by cacharle ### ########.fr */
-/* */
-/* ************************************************************************** */
-
-#include "minishell.h"
-#include "lexer.h"
-#include "eval.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));
-}
-
-
-t_tok_lst *st_stick_tokens(t_tok_lst *tokens)
-{
- t_tok_lst *curr;
-
- curr = tokens;
- while (curr != NULL)
- {
- // curr->next shouldn't be null
- if (curr->tag & TAG_STICK && curr->next != NULL)
- {
- curr->content = ft_strjoinf_fst(curr->content, curr->next->content);
- t_tok_lst *tmp = curr->next->next;
- curr->tag = curr->next->tag;
- ft_lstdelone((t_ftlst*)curr->next, free);
- curr->next = tmp;
- continue;
- }
- curr = curr->next;
- }
- return (tokens);
-}
-
-char **st_tokens_to_argv(t_tok_lst **tokens)
-{
- char **ret;
- size_t i;
- t_tok_lst *curr;
-
- curr = *tokens;
- ret = ft_calloc(ft_lstsize((t_ftlst*)curr) + 1, sizeof(char*));
- if (ret == NULL)
- return (NULL);
- i = 0;
- while (curr != NULL)
- {
- ret[i++] = curr->content;
- curr = curr->next;
- }
- tok_lst_destroy(tokens, NULL);
- return (ret);
-}
-
-bool escape(char *str, enum e_tok tag)
-{
- if (str[0] == '\\' && (tag & TAG_STR
- || ((tag & TAG_STR_DOUBLE) && ft_strchr("\\\"$", str[1]))))
- {
- ft_memmove(str, str + 1, ft_strlen(str + 1) + 1);
- return (true);
- }
- return (false);
-}
-
-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;
-
- 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);
-
- t_tok_lst *tmp = curr->next;
- curr->next = fields->next;
- (*curr_addr) = last;
- (*curr_addr)->next = tmp;
- free(fields);
- return len;
- }
- }
- return i;
-}
-
-char **preprocess(t_tok_lst **tokens, t_env env)
-{
- t_tok_lst *curr;
- enum e_tok prev_tag;
- char *str;
- size_t i;
-
- prev_tag = 0;
- curr = *tokens;
- while (curr != NULL)
- {
- if (curr->tag & (TAG_STR | TAG_STR_DOUBLE))
- {
- 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;
- }
- }
- prev_tag = curr->tag;
- curr = curr->next;
- }
- st_stick_tokens(*tokens);
- return (st_tokens_to_argv(tokens));
-}
-
-int preprocess_filename(t_tok_lst **tokens, t_env env, char **filename)
-{
- char **strs;
-
- if ((strs = preprocess(tokens, env)) == NULL
- || strs[0] == NULL)
- {
- free(strs);
- return (EVAL_FATAL);
- }
- if (strs[1] != NULL)
- {
- errorf("%s: ambiguous redidrect\n", strs[1]);
- ft_split_destroy(strs);
- return (1);
- }
- *filename = strs[0];
- free(strs);
- return (*filename == NULL ? EVAL_FATAL : 0);
-}
diff --git a/src/preprocess/filename.c b/src/preprocess/filename.c
new file mode 100644
index 0000000..0470554
--- /dev/null
+++ b/src/preprocess/filename.c
@@ -0,0 +1,35 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* filename.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* By: cacharle <me@cacharle.xyz> +#+ +:+ +#+ */
+/* +#+#+#+#+#+ +#+ */
+/* Created: 2020/10/09 15:29:04 by cacharle #+# #+# */
+/* Updated: 2020/10/09 15:30:03 by cacharle ### ########.fr */
+/* */
+/* ************************************************************************** */
+
+#include "eval.h"
+#include "lexer.h"
+#include "minishell.h"
+
+int preprocess_filename(t_tok_lst **tokens, t_env env, char **filename)
+{
+ char **strs;
+
+ if ((strs = preprocess(tokens, env)) == NULL || strs[0] == NULL)
+ {
+ free(strs);
+ return (EVAL_FATAL);
+ }
+ if (strs[1] != NULL)
+ {
+ errorf("%s: ambiguous redidrect\n", strs[1]);
+ ft_split_destroy(strs);
+ return (1);
+ }
+ *filename = strs[0];
+ free(strs);
+ return (*filename == NULL ? EVAL_FATAL : 0);
+}
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);
+}
diff --git a/src/preprocess/preprocess.c b/src/preprocess/preprocess.c
new file mode 100644
index 0000000..03ae203
--- /dev/null
+++ b/src/preprocess/preprocess.c
@@ -0,0 +1,98 @@
+/* ************************************************************************** */
+/* */
+/* ::: :::::::: */
+/* preprocess.c :+: :+: :+: */
+/* +:+ +:+ +:+ */
+/* 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 */
+/* */
+/* ************************************************************************** */
+
+#include "eval.h"
+#include "lexer.h"
+#include "minishell.h"
+
+t_tok_lst *st_stick_tokens(t_tok_lst *tokens)
+{
+ t_tok_lst *curr;
+ t_tok_lst *tmp;
+
+ curr = tokens;
+ while (curr != NULL)
+ {
+ if (curr->tag & TAG_STICK && curr->next != NULL)
+ {
+ curr->content = ft_strjoinf_fst(curr->content, curr->next->content);
+ tmp = curr->next->next;
+ curr->tag = curr->next->tag;
+ ft_lstdelone((t_ftlst *)curr->next, free);
+ curr->next = tmp;
+ continue;
+ }
+ curr = curr->next;
+ }
+ return (tokens);
+}
+
+char **st_tokens_to_argv(t_tok_lst **tokens)
+{
+ char **ret;
+ size_t i;
+ t_tok_lst *curr;
+
+ curr = *tokens;
+ ret = ft_calloc(ft_lstsize((t_ftlst *)curr) + 1, sizeof(char *));
+ if (ret == NULL)
+ return (NULL);
+ i = 0;
+ while (curr != NULL)
+ {
+ ret[i++] = curr->content;
+ curr = curr->next;
+ }
+ tok_lst_destroy(tokens, NULL);
+ return (ret);
+}
+
+bool escape(char *str, enum e_tok tag)
+{
+ if (str[0] == '\\' &&
+ (tag & TAG_STR || ((tag & TAG_STR_DOUBLE)
+ && ft_strchr("\\\"$", str[1]))))
+ {
+ ft_memmove(str, str + 1, ft_strlen(str + 1) + 1);
+ return (true);
+ }
+ return (false);
+}
+
+char **preprocess(t_tok_lst **tokens, t_env env)
+{
+ t_tok_lst *curr;
+ enum e_tok prev_tag;
+ char *str;
+ size_t i;
+
+ prev_tag = 0;
+ curr = *tokens;
+ while (curr != NULL)
+ {
+ if (curr->tag & (TAG_STR | TAG_STR_DOUBLE))
+ {
+ 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;
+ }
+ }
+ prev_tag = curr->tag;
+ curr = curr->next;
+ }
+ st_stick_tokens(*tokens);
+ return (st_tokens_to_argv(tokens));
+}