diff --git a/42sh/Makefile b/42sh/Makefile index 46c6db96..3ada95e4 100644 --- a/42sh/Makefile +++ b/42sh/Makefile @@ -73,6 +73,7 @@ exec/process_setexec.c\ exec/process_setgroup.c\ exec/process_setsig.c\ exec/redirect_dgreat.c\ +exec/redirect_dless.c\ exec/redirect_great.c\ exec/redirect_greatand.c\ exec/redirect_less.c\ @@ -104,6 +105,13 @@ glob/lib_perso/ft_strsubf.c\ glob/lib_perso/ft_tabdel.c\ glob/lib_perso/ft_tablen.c\ glob/match_pattern.c\ +history/add_str_in_history.c\ +history/history.c\ +history/history_parsing.c\ +history/history_parsing_toolz.c\ +history/history_parsing_toolz_2.c\ +history/list_toolz.c\ +history/surch_in_history.c\ job-control/builtin_bg.c\ job-control/builtin_fg.c\ job-control/builtin_jobs.c\ @@ -139,6 +147,7 @@ job-control/sigttin_handler.c\ job-control/sigttou_handler.c\ lexer/command_getoutput.c\ lexer/expand_bquotes.c\ +lexer/get_lexer_stack.c\ lexer/get_state_global.c\ lexer/get_state_redir.c\ lexer/lexer_backslash.c\ @@ -146,10 +155,12 @@ lexer/lexer_bquote.c\ lexer/lexer_comment.c\ lexer/lexer_default.c\ lexer/lexer_delim.c\ +lexer/lexer_dless.c\ lexer/lexer_dquote.c\ lexer/lexer_end.c\ lexer/lexer_great.c\ lexer/lexer_greatand.c\ +lexer/lexer_init.c\ lexer/lexer_less.c\ lexer/lexer_lessand.c\ lexer/lexer_lex.c\ @@ -172,13 +183,6 @@ line-editing/copy_cut_paste.c\ line-editing/ft_prompt.c\ line-editing/get_key.c\ line-editing/heredoc.c\ -line-editing/history/add_str_in_history.c\ -line-editing/history/history.c\ -line-editing/history/history_parsing.c\ -line-editing/history/history_parsing_toolz.c\ -line-editing/history/history_parsing_toolz_2.c\ -line-editing/history/list_toolz.c\ -line-editing/history/surch_in_history.c\ line-editing/home_end.c\ line-editing/lib_line_editing/tool_line.c\ line-editing/lib_line_editing/tool_line_2.c\ diff --git a/42sh/includes/lexer.h b/42sh/includes/lexer.h index 687203de..d89b0a54 100644 --- a/42sh/includes/lexer.h +++ b/42sh/includes/lexer.h @@ -45,10 +45,11 @@ enum e_lexstate SEP, WORD, NUMBER, - GREAT, LESS, - GREATAND, + GREAT, LESSAND, + GREATAND, + DLESS, QUOTE, DQUOTE, BQUOTE, @@ -74,6 +75,7 @@ struct s_lexer int pos; t_lexstate state; t_list *stack; + t_list *heredoc_stack; }; @@ -101,6 +103,8 @@ char *stack_to_prompt(t_list *stack); t_lexstate get_state_global(t_lexer *lexer); t_lexstate get_state_redir(t_lexer *lexer); +int get_lexer_stack(t_lexer lexer); +void lexer_init(t_lexer *lexer); int lexer_lex(t_list **alst, t_lexer *lexer); int lexer_default(t_list **alst, t_lexer *lexer); int lexer_newline(t_list **alst, t_lexer *lexer); @@ -110,8 +114,9 @@ int lexer_word(t_list **alst, t_lexer *lexer); int lexer_number(t_list **alst, t_lexer *lexer); int lexer_less(t_list **alst, t_lexer *lexer); int lexer_great(t_list **alst, t_lexer *lexer); -int lexer_lessand(t_list **alst, t_lexer *lexer); int lexer_greatand(t_list **alst, t_lexer *lexer); +int lexer_lessand(t_list **alst, t_lexer *lexer); +int lexer_dless(t_list **alst, t_lexer *lexer); int lexer_quote(t_list **alst, t_lexer *lexer); int lexer_dquote(t_list **alst, t_lexer *lexer); int lexer_bquote(t_list **alst, t_lexer *lexer); diff --git a/42sh/src/exec/process_redirect.c b/42sh/src/exec/process_redirect.c index a5560582..eec4d26d 100644 --- a/42sh/src/exec/process_redirect.c +++ b/42sh/src/exec/process_redirect.c @@ -16,7 +16,7 @@ t_redirmap g_redirmap[] = { {TK_LESS, redirect_less}, {TK_GREAT, redirect_great}, - /* {TK_DLESS, redirect_dless}, */ + {TK_DLESS, redirect_dless}, {TK_DGREAT, redirect_dgreat}, {TK_LESSAND, redirect_lessand}, {TK_GREATAND, redirect_greatand}, @@ -34,10 +34,7 @@ int process_redirect(t_process *p) { redir = redirs->content; if (redir->n > 9) - { - bad_fd(redir->n); - exit(1); - } + return (bad_fd(redir->n)); i = 0; while (g_redirmap[i].type) { diff --git a/42sh/src/exec/redirect_dless.c b/42sh/src/exec/redirect_dless.c new file mode 100644 index 00000000..241f6e1f --- /dev/null +++ b/42sh/src/exec/redirect_dless.c @@ -0,0 +1,27 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* redirect_dless.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: jhalford +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2017/02/06 22:09:53 by jhalford #+# #+# */ +/* Updated: 2017/02/07 16:05:09 by jhalford ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "exec.h" + +int redirect_dless(t_redir *redir) +{ + int fds[2]; + char *str; + + pipe(fds); + str = redir->word.word; + write(fds[PIPE_WRITE], str, ft_strlen(str)); + close(fds[PIPE_WRITE]); + dup2(fds[PIPE_READ], 0); + close(fds[PIPE_READ]); + return (0); +} diff --git a/42sh/src/exec/redirect_greatand.c b/42sh/src/exec/redirect_greatand.c index 6e4bf37f..70658424 100644 --- a/42sh/src/exec/redirect_greatand.c +++ b/42sh/src/exec/redirect_greatand.c @@ -17,6 +17,7 @@ int redirect_greatand(t_redir *redir) int fdold; int fdnew; + DG("redir greatand"); if (redir->close) { close(redir->n); diff --git a/42sh/src/line-editing/history/add_str_in_history.c b/42sh/src/history/add_str_in_history.c similarity index 100% rename from 42sh/src/line-editing/history/add_str_in_history.c rename to 42sh/src/history/add_str_in_history.c diff --git a/42sh/src/line-editing/history/history.c b/42sh/src/history/history.c similarity index 100% rename from 42sh/src/line-editing/history/history.c rename to 42sh/src/history/history.c diff --git a/42sh/src/line-editing/history/history_parsing.c b/42sh/src/history/history_parsing.c similarity index 100% rename from 42sh/src/line-editing/history/history_parsing.c rename to 42sh/src/history/history_parsing.c diff --git a/42sh/src/line-editing/history/history_parsing_toolz.c b/42sh/src/history/history_parsing_toolz.c similarity index 100% rename from 42sh/src/line-editing/history/history_parsing_toolz.c rename to 42sh/src/history/history_parsing_toolz.c diff --git a/42sh/src/line-editing/history/history_parsing_toolz_2.c b/42sh/src/history/history_parsing_toolz_2.c similarity index 100% rename from 42sh/src/line-editing/history/history_parsing_toolz_2.c rename to 42sh/src/history/history_parsing_toolz_2.c diff --git a/42sh/src/line-editing/history/list_toolz.c b/42sh/src/history/list_toolz.c similarity index 100% rename from 42sh/src/line-editing/history/list_toolz.c rename to 42sh/src/history/list_toolz.c diff --git a/42sh/src/line-editing/history/surch_in_history.c b/42sh/src/history/surch_in_history.c similarity index 100% rename from 42sh/src/line-editing/history/surch_in_history.c rename to 42sh/src/history/surch_in_history.c diff --git a/42sh/src/job-control/job_wait.c b/42sh/src/job-control/job_wait.c index 6cd87253..62f5ebef 100644 --- a/42sh/src/job-control/job_wait.c +++ b/42sh/src/job-control/job_wait.c @@ -17,7 +17,6 @@ int job_wait(int id) pid_t pid; int status; - DG("gonna wait [%i]", id); if (job_is_stopped(id)) return (0); job_update_status(); diff --git a/42sh/src/lexer/get_lexer_stack.c b/42sh/src/lexer/get_lexer_stack.c new file mode 100644 index 00000000..10ce9b70 --- /dev/null +++ b/42sh/src/lexer/get_lexer_stack.c @@ -0,0 +1,6 @@ +#include "lexer.h" + +int get_lexer_stack(t_lexer lexer) +{ + return (lexer.stack ? *(int*)lexer.stack->content : 0); +} diff --git a/42sh/src/lexer/lexer_dless.c b/42sh/src/lexer/lexer_dless.c new file mode 100644 index 00000000..f0e0ee4d --- /dev/null +++ b/42sh/src/lexer/lexer_dless.c @@ -0,0 +1,41 @@ +#include "lexer.h" + +int lexer_dless(t_list **alst, t_lexer *lexer) +{ + t_list *heredoc_lst; + t_token *eof_tok; + t_token *heredoc_tok; + + (void)alst; + (void)lexer; + heredoc_lst = *(t_list**)lexer->heredoc_stack->content; + heredoc_tok = heredoc_lst->content; + if (!(heredoc_lst->next)) + { + ft_dprintf(2, "{red}%s: parse error near `\\n'{eoc}\n", SHELL_NAME); + return (1); + } + eof_tok = heredoc_lst->next->content; + if (!(eof_tok->type == TK_WORD)) + { + ft_dprintf(2, "{red}%s: expected word token after <<{eoc}\n", SHELL_NAME); + return (1); + } + DG("heredoc contains [%s]", heredoc_tok->data); + DG("heredoc ends at [%s]", eof_tok->data); + DG("input is [%s]", lexer->str + lexer->pos); + if (ft_strcmp(eof_tok->data, lexer->str + lexer->pos) == 0) + { + pop(&lexer->stack); + pop(&lexer->heredoc_stack); + while (lexer->str[++lexer->pos]) + ; + ft_strappend(&lexer->str, (char[]){'\n', 0}); + lexer->pos++; + return (0); + } + else + while (lexer->str[lexer->pos]) + token_append_char(heredoc_tok, lexer->str[lexer->pos++], 0, 0); + return (lexer_end(alst, lexer)); +} diff --git a/42sh/src/lexer/lexer_end.c b/42sh/src/lexer/lexer_end.c index f7650e81..2ec70dd2 100644 --- a/42sh/src/lexer/lexer_end.c +++ b/42sh/src/lexer/lexer_end.c @@ -4,15 +4,23 @@ int lexer_end(t_list **alst, t_lexer *lexer) { t_token *token; - DG("check"); - if (*alst && (lexer->state == QUOTE + if ((*alst && (lexer->state == QUOTE || lexer->state == DQUOTE || lexer->state == BQUOTE)) + || get_lexer_stack(*lexer) == DLESS) { - token = (*alst)->content; ft_strappend(&lexer->str, (char[]){'\n', 0}); - token_append(token, lexer, 1, 0); lexer->pos++; + if (get_lexer_stack(*lexer) == DLESS) + { + token = (*(t_list**)lexer->heredoc_stack->content)->content; + token_append_char(token, '\n', 0, 0); + } + else + { + token = (*alst)->content; + token_append_char(token, '\n', 1, 0); + } return (0); } return (0); diff --git a/42sh/src/lexer/lexer_init.c b/42sh/src/lexer/lexer_init.c new file mode 100644 index 00000000..230ee3f6 --- /dev/null +++ b/42sh/src/lexer/lexer_init.c @@ -0,0 +1,10 @@ +#include "lexer.h" + +void lexer_init(t_lexer *lexer) +{ + lexer->str = NULL; + lexer->pos = 0; + lexer->state = DEFAULT; + lexer->stack = NULL; + lexer->heredoc_stack = NULL; +} diff --git a/42sh/src/lexer/lexer_less.c b/42sh/src/lexer/lexer_less.c index 00798f44..4f8eae63 100644 --- a/42sh/src/lexer/lexer_less.c +++ b/42sh/src/lexer/lexer_less.c @@ -28,11 +28,13 @@ int lexer_less(t_list **alst, t_lexer *lexer) } if (lexer->str[lexer->pos + 1] == '<') { + token_free(token, 0); + (*alst)->content = token_init(); token->type = TK_DLESS; - lexer->pos++; - token_append(token, lexer, 0, 0); - lexer->pos++; + lexer->pos += 2; + push(&lexer->stack, DLESS); lexer->state = DEFAULT; + ft_lsteadd(&lexer->heredoc_stack, ft_lstnew(alst, sizeof(alst))); return (lexer_lex(&(*alst)->next, lexer)); } else diff --git a/42sh/src/lexer/lexer_lex.c b/42sh/src/lexer/lexer_lex.c index 9472a565..f6614e5a 100644 --- a/42sh/src/lexer/lexer_lex.c +++ b/42sh/src/lexer/lexer_lex.c @@ -20,10 +20,11 @@ int (*g_lexer[])(t_list **alst, t_lexer *lexer) = &lexer_sep, &lexer_word, &lexer_number, - &lexer_great, &lexer_less, - &lexer_greatand, + &lexer_great, &lexer_lessand, + &lexer_greatand, + &lexer_dless, &lexer_quote, &lexer_dquote, &lexer_bquote, diff --git a/42sh/src/lexer/lexer_sep.c b/42sh/src/lexer/lexer_sep.c index 581f2395..a393f714 100644 --- a/42sh/src/lexer/lexer_sep.c +++ b/42sh/src/lexer/lexer_sep.c @@ -18,6 +18,7 @@ int lexer_sep(t_list **alst, t_lexer *lexer) char c; char cn; + lexer->state = DEFAULT; if (*alst) { token = (*alst)->content; diff --git a/42sh/src/lexer/stack_to_prompt.c b/42sh/src/lexer/stack_to_prompt.c index 385ffc89..b79c208b 100644 --- a/42sh/src/lexer/stack_to_prompt.c +++ b/42sh/src/lexer/stack_to_prompt.c @@ -31,6 +31,8 @@ char *stack_to_prompt(t_list *stack) return ("dquote bquote> "); else if (top == PAREN) return ("subsh> "); + else if (top == DLESS) + return ("heredoc> "); else return ("error> "); } diff --git a/42sh/src/main/main.c b/42sh/src/main/main.c index 907ce438..6aad9f87 100644 --- a/42sh/src/main/main.c +++ b/42sh/src/main/main.c @@ -18,10 +18,8 @@ int non_interactive_shell(char *command) t_lexer lexer; t_btree *ast; - lexer.pos = 0; - lexer.state = DEFAULT; + lexer_init(&lexer); lexer.str = command; - lexer.stack = NULL; token = NULL; ast = NULL; while (lexer.str[lexer.pos]) @@ -43,6 +41,7 @@ int non_interactive_shell(char *command) } return (0); } + int interactive_shell() { t_list *token; @@ -50,27 +49,26 @@ int interactive_shell() t_lexer lexer; t_btree *ast; - lexer.pos = 0; - lexer.state = DEFAULT; - lexer.str = NULL; + lexer_init(&lexer); token = NULL; - lexer.stack = NULL; ast = NULL; do { ft_strappend(&lexer.str, readline(stack_to_prompt(lexer.stack))); - if (lexer.stack && *(int*)lexer.stack->content == BACKSLASH) + if (get_lexer_stack(lexer) == BACKSLASH) pop(&lexer.stack); + else if (get_lexer_stack(lexer) == DLESS) + lexer.state = DLESS; ltoken = ft_lstlast(token); - lexer_lex((token ? <oken : &token), &lexer); + if (lexer_lex((token ? <oken : &token), &lexer)) + return (1); DG("[{mag}%s{eoc}] stack=[%i] state=[%i]", lexer.str, lexer.stack ? *(int*)lexer.stack->content : 0, lexer.state); token_print(token); - } while (lexer.stack); + } while (get_lexer_stack(lexer)); if (bquotes_expand(&token)) return (1); if (!token) return (0); ft_add_str_in_history(lexer.str); - token_print(token); if (ft_parse(&ast, &token)) return (1); btree_print(STDBUG, ast, &ft_putast); @@ -87,7 +85,7 @@ int main(int ac, char **av) data = data_singleton(); setlocale(LC_ALL, ""); shell_init(ac, av); - DG("{inv}{bol}{gre}start of shell{eoc} pid=%i pgrp=%i job_control is %s", getpid(), getpgrp(), SH_HAS_JOBC(data->opts) ? "ON" : "OFF"); + DG("{inv}{bol}{gre}start of shell{eoc} JOBC is %s", SH_HAS_JOBC(data->opts)?"ON":"OFF"); if (SH_IS_INTERACTIVE(data->opts)) { while (1) diff --git a/42sh/src/parser/parse_dless.c b/42sh/src/parser/parse_dless.c index 20d91421..1b75baa2 100644 --- a/42sh/src/parser/parse_dless.c +++ b/42sh/src/parser/parse_dless.c @@ -26,7 +26,8 @@ int parse_dless(t_btree **ast, t_list **start, t_list **lst) next_tok = (*lst)->next->content; if (next_tok->type != TK_WORD) return (1); - node->data.redir.word.word = ft_strdup(next_tok->data); + node->data.redir.word.word = ft_strdup(tok->data); + node->data.redir.n = 0; ft_lst_delif(start, (*lst)->content, &ft_addrcmp, &token_free); ft_lst_delif(start, (*lst)->next->content, &ft_addrcmp, &token_free); ft_parse(&(*ast)->left, start);