From 58ef5a4a038e877383c789de9a226f186ae124ee Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sat, 30 Oct 2021 12:44:06 +0200 Subject: [PATCH 1/4] Fix free for final empty token. --- srcs/lexing.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/srcs/lexing.c b/srcs/lexing.c index 5aa6b96..cb69889 100644 --- a/srcs/lexing.c +++ b/srcs/lexing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ -/* Updated: 2021/10/24 19:53:40 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 12:43:05 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,9 +29,19 @@ enum e_fill_token_return DELIMITE_TOKEN }; +t_list *ft_lstbeforelast(t_list *lst) // tmp +{ + if (!lst || !lst->next) + return (NULL); + while (lst->next->next) + lst = lst->next; + return (lst); +} + t_token *input_to_tokens(char *input) { t_token *t_head; + t_token *t_tmp; size_t input_len; input_len = ft_strlen(input); @@ -40,11 +50,15 @@ t_token *input_to_tokens(char *input) return (ft_retp_perror(NULL, "alloc_token() error")); if (!tokenize_input(t_head, input, input_len)) return (ft_lstclear((t_list **)&t_head, free)); + t_tmp = ft_lstbeforelast((t_list *)t_head); + if (t_tmp && !t_tmp->next->id) + { + ft_lstdelone((t_list *)t_tmp->next, free); + t_tmp->next = NULL; + } return (t_head); } -// TODO : Fix final space saved after a pipe like in "cmd | " -// "cmd | " should behave like "cmd |" static int tokenize_input(t_token *t, char *input, size_t input_len) { int i; @@ -65,10 +79,8 @@ static int tokenize_input(t_token *t, char *input, size_t input_len) t_i = 0; } } - if (!t->id && t_i) // Fix parser syntax, but last elem must still be free - t->id = T_WORD; -/* if (!t->id) - t->id = T_WORD; */ + if (!t->id && t_i) + t->id = T_WORD; return (1); } From ab2aa509df17f53ae79b881416459ba4e15ebf22 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sat, 30 Oct 2021 16:39:24 +0200 Subject: [PATCH 2/4] signals and termios WIP + shell script placeholder + generics functions + valgrind add_history() supp + misc --- Makefile | 5 +- headers/minishell.h | 7 +-- headers/minishell_prototypes.h | 13 ++++-- headers/minishell_structs.h | 23 ++++++---- parsing.txt | 4 +- srcs/free.c | 7 ++- srcs/generic.c | 17 +++++-- srcs/init.c | 14 ++++-- srcs/lexing.c | 13 +----- srcs/main.c | 9 ++-- srcs/parsing/parsing.c | 4 +- srcs/shell_loop.c | 73 ++++++++++++++++------------- srcs/shell_script.c | 19 ++++++++ srcs/signals.c | 84 ++++++++++++++++++++++++++++++++++ srcs/terminal.c | 76 ++++++++++++++++++++++++++++++ valgrind_readline.supp | 7 +++ 16 files changed, 302 insertions(+), 73 deletions(-) create mode 100644 srcs/shell_script.c create mode 100644 srcs/signals.c create mode 100644 srcs/terminal.c diff --git a/Makefile b/Makefile index b239c10..cd67765 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ NAME = minishell CC = clang -CFLAGS = -Wall -Wextra -Werror $(INCLUDES) -g +CFLAGS = -Wall -Wextra $(INCLUDES) -g # add -Werror, del -g VPATH = $(DIR_SRCS) DIR_SRCS = srcs srcs/builtins srcs/parsing @@ -22,7 +22,8 @@ LIBFT_D = ./libft LIBFT = $(LIBFT_D)/libft.a SRCS = main.c init.c free.c generic.c \ - shell_loop.c \ + signals.c terminal.c \ + shell_loop.c shell_script.c \ lexing.c \ parsing.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ diff --git a/headers/minishell.h b/headers/minishell.h index 47ea867..4ff4d89 100644 --- a/headers/minishell.h +++ b/headers/minishell.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/03 19:14:46 by lperrey #+# #+# */ -/* Updated: 2021/10/13 16:09:32 by lperrey ### ########.fr */ +/* Updated: 2021/10/26 14:53:32 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,6 +15,7 @@ # include "libft.h" # include # include +# include # include # include # include @@ -52,8 +53,8 @@ ** : open() ** : read(), write(), close(), fork(), getcwd(), chdir(), ** stat(), lstat(), fstat(), execve(), dup(), dup2(), pipe(), -** isatty(), ttyname(), ttyslot(), ioctl(), -** tcsetattr(), tcgetattr() +** isatty(), ttyname(), ttyslot(), tcsetattr(), tcgetattr() +** : ioctl() ** : malloc(), free(), exit(), getenv() ** : strerror(), define NULL, define size_t ** : define errno diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index f6b043f..3b491b5 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:59:58 by lperrey #+# #+# */ -/* Updated: 2021/10/24 19:20:09 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 14:16:25 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,9 +15,15 @@ // Init int init(t_all *c, char *envp[]); +int set_signals_handling(struct sigaction *ori_signal_behaviour, + struct sigaction *signal_behaviour); +int set_terminal_attributes(struct termios *ori_termios, + struct termios *interactive_termios, + int *termios_changed); -// Shell loop +// Shell modes void shell_loop(t_all *c); +void shell_script(t_all *c); // Lexer t_token *input_to_tokens(char *input); @@ -43,7 +49,8 @@ char *ft_strjoinfree_s2(const char *s1, char *s2); void ft_lstprint(t_list *lst, int fd); int ft_isinset_str(char *str, char *set); size_t ft_2d_arrlen(void *ptr); // Replace ft_arrlen() -void *ft_dup_2d_arr(void *ptr); +char **ft_dup_2d_char_arr(char **ptr); void *ft_resize_2d_arr(void *ptr, size_t add_nbr); +t_list *ft_lstbeforelast(t_list *lst); #endif diff --git a/headers/minishell_structs.h b/headers/minishell_structs.h index 183ffba..c5ba834 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -6,13 +6,16 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:52 by lperrey #+# #+# */ -/* Updated: 2021/10/24 19:18:28 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 13:31:07 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef MINISHELL_STRUCTS_H # define MINISHELL_STRUCTS_H +struct s_all; +struct s_all *g_all; + enum e_token_id { T_TOKEN = 0, @@ -31,7 +34,6 @@ typedef struct s_token enum e_token_id id; } t_token; -struct s_all; typedef int (*t_builtin_ptr)(int,char **,struct s_all *); typedef struct s_cmd @@ -45,12 +47,17 @@ typedef struct s_cmd typedef struct s_all { - t_cmd **cmd_arr; - char **envp; - char *prompt_base; - char *prompt; - t_token *token_list; - int last_exit_status; + t_cmd **cmd_arr; + char **envp; + char *prompt_base; + char *prompt; + t_token *token_list; + int last_exit_status; + struct termios ori_termios; + struct termios interactive_termios; + int termios_changed; + struct sigaction ori_signal_behaviour; + struct sigaction signal_behaviour; } t_all; #endif diff --git a/parsing.txt b/parsing.txt index c53ecb8..1c9627b 100644 --- a/parsing.txt +++ b/parsing.txt @@ -15,8 +15,8 @@ https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18 ------------------------------------------------------- */ %start program %% -pipeline : command - | pipe_sequence '|' command +pipeline : command + | pipeline '|' command ; command : cmd_prefix cmd_name cmd_suffix | cmd_prefix cmd_name diff --git a/srcs/free.c b/srcs/free.c index b2b6468..d02f438 100644 --- a/srcs/free.c +++ b/srcs/free.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/10 23:53:17 by lperrey #+# #+# */ -/* Updated: 2021/10/22 13:35:33 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 14:18:09 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,6 +17,9 @@ int free_exit(t_all *c, int exit_status) free(c->prompt_base); free(c->prompt); ft_lstclear((t_list **)&c->token_list, free); // a voir avec Hugo, il y a un truc qui me semble superflu dans la fonction - exit(exit_status); ft_free_2d_arr(c->envp); + if (c->termios_changed) + tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); + rl_clear_history(); + exit(exit_status); } diff --git a/srcs/generic.c b/srcs/generic.c index 43f2b9c..3d6e29e 100644 --- a/srcs/generic.c +++ b/srcs/generic.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:25:35 by lperrey #+# #+# */ -/* Updated: 2021/10/23 15:19:07 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 12:30:10 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -85,7 +85,7 @@ size_t ft_2d_arrlen(void *ptr) // Replace ft_arrlen() return (len); } -void *ft_dup_2d_arr(void *ptr) +char **ft_dup_2d_char_arr(char **ptr) { unsigned int i; char **arr; @@ -98,7 +98,9 @@ void *ft_dup_2d_arr(void *ptr) i = 0; while (arr[i]) { - new_arr[i] = arr[i]; + new_arr[i] = ft_strdup(arr[i]); + if (!new_arr[i]) + return (ft_retp_free(NULL, new_arr, ft_free_2d_arr)); i++; } new_arr[i] = NULL; @@ -122,3 +124,12 @@ void *ft_resize_2d_arr(void *ptr, size_t add_nbr) free(arr); return (new_arr); } + +t_list *ft_lstbeforelast(t_list *lst) +{ + if (!lst || !lst->next) + return (NULL); + while (lst->next->next) + lst = lst->next; + return (lst); +} diff --git a/srcs/init.c b/srcs/init.c index 6264069..26f826e 100644 --- a/srcs/init.c +++ b/srcs/init.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 09:22:12 by lperrey #+# #+# */ -/* Updated: 2021/10/23 16:04:03 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 14:17:41 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,16 +17,24 @@ static char *init_prompt(char *prompt_base); int init(t_all *c, char *envp[]) { + g_all = c; ft_bzero(c, sizeof *c); - c->envp = ft_dup_2d_arr(envp); + c->envp = ft_dup_2d_char_arr(envp); if (!c->envp) - return (ft_reti_perror(0, "ft_dup_2d_arr(envp) error")); + return (ft_reti_perror(0, "ft_dup_2d_char_arr(envp) error")); c->prompt_base = init_prompt_base(); if (!c->prompt_base) return (ft_reti_perror(0, "init_prompt_base() error")); c->prompt = init_prompt(c->prompt_base); if (!c->prompt) return (ft_reti_perror(0, "init_prompt() error")); + set_signals_handling(&c->ori_signal_behaviour, &c->signal_behaviour); + if (isatty(STDIN_FILENO)) + { + if (!set_terminal_attributes(&c->ori_termios, &c->interactive_termios, + &c->termios_changed)) + return (ft_reti_perror(0, "set_terminal_attributes() error")); + } return (1); } diff --git a/srcs/lexing.c b/srcs/lexing.c index cb69889..5036a54 100644 --- a/srcs/lexing.c +++ b/srcs/lexing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ -/* Updated: 2021/10/30 12:43:05 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 14:19:42 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,15 +29,6 @@ enum e_fill_token_return DELIMITE_TOKEN }; -t_list *ft_lstbeforelast(t_list *lst) // tmp -{ - if (!lst || !lst->next) - return (NULL); - while (lst->next->next) - lst = lst->next; - return (lst); -} - t_token *input_to_tokens(char *input) { t_token *t_head; @@ -50,7 +41,7 @@ t_token *input_to_tokens(char *input) return (ft_retp_perror(NULL, "alloc_token() error")); if (!tokenize_input(t_head, input, input_len)) return (ft_lstclear((t_list **)&t_head, free)); - t_tmp = ft_lstbeforelast((t_list *)t_head); + t_tmp = (t_token *)ft_lstbeforelast((t_list *)t_head); if (t_tmp && !t_tmp->next->id) { ft_lstdelone((t_list *)t_tmp->next, free); diff --git a/srcs/main.c b/srcs/main.c index c651cd4..e18a404 100644 --- a/srcs/main.c +++ b/srcs/main.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/10/22 10:33:00 by lperrey ### ########.fr */ +/* Updated: 2021/10/29 01:59:04 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,7 +19,10 @@ int main(int argc, char *argv[], char *envp[]) (void)argc; (void)argv; if (!init(&c, envp)) - exit(EXIT_FAILURE); - shell_loop(&c); + free_exit(&c, EXIT_FAILURE); + if (isatty(STDIN_FILENO)) + shell_loop(&c); + else + shell_script(&c); return (0); } diff --git a/srcs/parsing/parsing.c b/srcs/parsing/parsing.c index 49c9fd8..99ce7ea 100644 --- a/srcs/parsing/parsing.c +++ b/srcs/parsing/parsing.c @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/24 10:52:40 by lperrey #+# #+# */ -/* Updated: 2021/10/24 19:19:08 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 15:33:27 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -68,7 +68,7 @@ t_cmd **parsing(t_token *token_list) %start program %% pipeline : command - | pipe_sequence '|' command + | pipeline '|' command ; command : cmd_prefix cmd_name cmd_suffix | cmd_prefix cmd_name diff --git a/srcs/shell_loop.c b/srcs/shell_loop.c index 2aa41f6..16d684e 100644 --- a/srcs/shell_loop.c +++ b/srcs/shell_loop.c @@ -6,13 +6,15 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/04 05:59:26 by lperrey #+# #+# */ -/* Updated: 2021/10/24 19:17:03 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 15:32:44 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" -static char **tokens_list_to_argv(t_token *t); // temp test +//static char **tokens_list_to_argv(t_token *t); // temp test +void sigint_handler(int signum); //tmp +void sigquit_aka_eof_handler(int signum); //tmp void shell_loop(t_all *c) { @@ -28,11 +30,43 @@ void shell_loop(t_all *c) { add_history(line_input); c->token_list = input_to_tokens(line_input); + + // TEMP + // A faire aprés être sortie du mode interactif + // - Ignorer tout les signaux + // - Remettre ori_termios + c->signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGINT, &c->signal_behaviour, NULL); + sigaction(SIGQUIT, &c->signal_behaviour, NULL); + tcsetattr(STDIN_FILENO, TCSANOW, &c->ori_termios); + if (!fork()) + { + char *arg_test[3]; + + arg_test[0] = ft_strdup("sleep"); + arg_test[1] = ft_strdup("3"); + arg_test[2] = NULL; + sigaction(SIGQUIT, &c->ori_signal_behaviour, NULL); + sigaction(SIGINT, &c->ori_signal_behaviour, NULL); + execve("/bin/sleep", arg_test, c->envp); + } + else + { + int wait_test; + wait(&wait_test); + c->signal_behaviour.sa_handler = sigint_handler; + sigaction(SIGINT, &c->signal_behaviour, NULL); + c->signal_behaviour.sa_handler = SIG_IGN; + sigaction(SIGQUIT, &c->signal_behaviour, NULL); + tcsetattr(STDIN_FILENO, TCSANOW, &c->interactive_termios); + } + + // EXEC_PIPES_AND_CO() // temp placeholder - if (ft_strncmp(c->token_list->content, "env", 4) == 0) +/* if (ft_strncmp(c->token_list->content, "env", 4) == 0) builtin_env(0, NULL, c); else if (ft_strncmp(c->token_list->content, "exit", 5) == 0) builtin_exit(0, NULL, c); @@ -48,12 +82,14 @@ void shell_loop(t_all *c) ft_putstr_fd("TOKENS LIST :\n-----------\n", 1); ft_lstprint((t_list *)c->token_list, 1); ft_lstclear((t_list **)&c->token_list, free); - } + } */ } + else if (!line_input) + write(1, "\n", 1); } } -static char **tokens_list_to_argv(t_token *t) // temp test +/* static char **tokens_list_to_argv(t_token *t) // temp test { size_t i; char **argv; @@ -68,29 +104,4 @@ static char **tokens_list_to_argv(t_token *t) // temp test t = t->next; } return (argv); -} - -void wip_test() -{ - char term_desc[2048]; - char *term_type; - int term_width; - int term_height; - int ret; - - term_type = getenv("TERM"); - if (term_type == 0) - ft_putstr_fd("Specify a terminal type with `setenv TERM '.\n", 2); - ret = tgetent(term_desc, term_type); - if (ret < 0) - ft_putstr_fd("Could not access the termcap data base.\n", 2); - if (ret == 0) - ft_putstr_fd("Terminal type `%s' is not defined.\n", 2); - term_height = tgetnum ("li"); - term_width = tgetnum ("co"); - /* Extract information that termcap functions use. */ -/* temp = tgetstr ("pc", BUFFADDR); - PC = temp ? *temp : 0; - BC = tgetstr ("le", BUFFADDR); - UP = tgetstr ("up", BUFFADDR); */ -} +} */ diff --git a/srcs/shell_script.c b/srcs/shell_script.c new file mode 100644 index 0000000..017d4aa --- /dev/null +++ b/srcs/shell_script.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* shell_script.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/26 23:47:44 by lperrey #+# #+# */ +/* Updated: 2021/10/30 15:01:13 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void shell_script(t_all *c) // WIP +{ + ft_putstr_fd("Shell Script Placeholder\n", 1); + free_exit(c, EXIT_SUCCESS); +} diff --git a/srcs/signals.c b/srcs/signals.c new file mode 100644 index 0000000..f715783 --- /dev/null +++ b/srcs/signals.c @@ -0,0 +1,84 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* signals.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/23 18:56:53 by lperrey #+# #+# */ +/* Updated: 2021/10/30 14:28:08 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void sigint_handler(int signum) +{ + // Comment virer LE ^D De l'affichage ? Il ne fait pas partie de "rl_line_buffer". + if (rl_line_buffer && *rl_line_buffer) + { + return ; + } + else + { + free_exit(g_all, g_all->last_exit_status); + } + return ; +} + +/* void sigquit_aka_eof_handler(int signum) +{ + //ft_putstr_fd("TESTS\n", 1); + ft_putstr_fd("\n", 1); + rl_replace_line("", 1); + rl_on_new_line(); + rl_redisplay(); + return ; +} */ + +int set_signals_handling(struct sigaction *ori_signal_behaviour, + struct sigaction *signal_behaviour) +{ + ori_signal_behaviour->sa_handler = SIG_DFL; + + /* ctrl-D exit the shell. + eof = ^D; */ + signal_behaviour->sa_handler = sigint_handler; + sigaction(SIGINT, signal_behaviour, NULL); + + /* ctrl-\ do nothing. + quit = ^\; */ + signal_behaviour->sa_handler = SIG_IGN; + //signal_behaviour->sa_handler = sigquit_aka_eof_handler; + sigaction(SIGQUIT, signal_behaviour, NULL); + + /* + ** remap (^D to ^C) and (^C to ^D) in terminal + ** ^D is now "SIGINT" (handle here) + ** ^C is now EOF (handle in shell_loop()) + */ + return (1); +} + +/* +ctrl-C print a new prompt on a newline. +intr = ^C; +ctrl-D exit the shell. +eof = ^D; +ctrl-\ do nothing. +quit = ^\; +*/ + +/* +speed 38400 baud; rows 22; columns 90; line = 0; +erase = ^?; kill = ^U; +eol = M-^?; eol2 = M-^?; +swtch = M-^?; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; +discard = ^O; min = 1; time = 0; +-parenb -parodd -cmspar cs8 hupcl -cstopb cread -clocal -crtscts +-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc ixany +imaxbel iutf8 +opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 +isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke +-flusho -extproc +*/ diff --git a/srcs/terminal.c b/srcs/terminal.c new file mode 100644 index 0000000..b33f969 --- /dev/null +++ b/srcs/terminal.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* terminal.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/27 00:10:04 by lperrey #+# #+# */ +/* Updated: 2021/10/30 14:17:16 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +#define CTRL_C 03 +#define CTRL_D 04 +#define CTRL_BACKSLASH 034 + +int set_terminal_attributes(struct termios *ori_termios, + struct termios *interactive_termios, + int *termios_changed) +{ + tcgetattr(STDIN_FILENO, ori_termios); + *interactive_termios = *ori_termios; + + interactive_termios->c_cc[VINTR] = CTRL_D; + interactive_termios->c_cc[VEOF] = CTRL_C; + + //interactive_termios->c_cc[VQUIT] = CTRL_C; + //interactive_termios->c_cc[VEOF] = CTRL_BACKSLASH; + + //interactive_termios->c_cc[VEOL] = CTRL_C; + + *termios_changed = 1; + tcsetattr(STDIN_FILENO, TCSANOW, interactive_termios); + + return (1); +} + + //printf("STDIN_FILENO = %s\n ", ttyname(STDIN_FILENO)); + //printf("STDOUT_FILENO = %s\n ", ttyname(STDOUT_FILENO)); + //printf("STDERR_FILENO = %s\n ", ttyname(STDERR_FILENO)); + //ft_putendl_fd(ttyname(STDIN_FILENO), 1); + //ft_putendl_fd(ttyname(STDOUT_FILENO), 1); + //ft_putendl_fd(ttyname(STDERR_FILENO), 1); + // ft_printf("BEFORE\n"); + // ft_printf("i_io.c_cc[VEOF] = %i\ni_termios.c_cc[VINTR] = %i\n", (*interactive_termios)->c_cc[VEOF], (*interactive_termios)->c_cc[VINTR]); + // ft_printf("o_io.c_cc[VEOF] = %i\no_termios.c_cc[VINTR] = %i\n", (*ori_termios)->c_cc[VEOF], (*ori_termios)->c_cc[VINTR]); + // ft_printf("AFTER\n"); + // ft_printf("i_io.c_cc[VEOF] = %i\ni_termios.c_cc[VINTR] = %i\n", (*interactive_termios)->c_cc[VEOF], (*interactive_termios)->c_cc[VINTR]); + // ft_printf("o_io.c_cc[VEOF] = %i\no_termios.c_cc[VINTR] = %i\n", (*ori_termios)->c_cc[VEOF], (*ori_termios)->c_cc[VINTR]); + +void wip_test() +{ + char term_desc[2048]; + char *term_type; + int term_width; + int term_height; + int ret; + + term_type = getenv("TERM"); + if (term_type == 0) + ft_putstr_fd("Specify a terminal type with `setenv TERM '.\n", 2); + ret = tgetent(term_desc, term_type); + if (ret < 0) + ft_putstr_fd("Could not access the termcap data base.\n", 2); + if (ret == 0) + ft_putstr_fd("Terminal type `%s' is not defined.\n", 2); + term_height = tgetnum ("li"); + term_width = tgetnum ("co"); + /* Extract information that termcap functions use. */ +/* temp = tgetstr ("pc", BUFFADDR); + PC = temp ? *temp : 0; + BC = tgetstr ("le", BUFFADDR); + UP = tgetstr ("up", BUFFADDR); */ +} diff --git a/valgrind_readline.supp b/valgrind_readline.supp index b632bcc..f1f3bc4 100644 --- a/valgrind_readline.supp +++ b/valgrind_readline.supp @@ -4,3 +4,10 @@ ... fun:readline } + +{ + + Memcheck:Leak + ... + fun:add_history +} From c0ef57499addcfb4fec41b2c990d52badfd1e785 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sat, 30 Oct 2021 22:47:02 +0200 Subject: [PATCH 3/4] lexing refactoring --- Makefile | 4 +- headers/minishell_macro.h | 8 +- srcs/lexing.c | 196 ---------------------------------- srcs/lexing/check_operators.c | 65 +++++++++++ srcs/lexing/fill_token.c | 77 +++++++++++++ srcs/lexing/lexing.c | 76 +++++++++++++ 6 files changed, 227 insertions(+), 199 deletions(-) delete mode 100644 srcs/lexing.c create mode 100644 srcs/lexing/check_operators.c create mode 100644 srcs/lexing/fill_token.c create mode 100644 srcs/lexing/lexing.c diff --git a/Makefile b/Makefile index cd67765..0f7d936 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = clang CFLAGS = -Wall -Wextra $(INCLUDES) -g # add -Werror, del -g VPATH = $(DIR_SRCS) -DIR_SRCS = srcs srcs/builtins srcs/parsing +DIR_SRCS = srcs srcs/builtins srcs/lexing srcs/parsing INCLUDES = -I$(HEADERS_D) -I$(LIBFT_D) @@ -24,7 +24,7 @@ LIBFT = $(LIBFT_D)/libft.a SRCS = main.c init.c free.c generic.c \ signals.c terminal.c \ shell_loop.c shell_script.c \ - lexing.c \ + lexing.c fill_token.c check_operators.c \ parsing.c \ valid_syntax.c valid_pipeline.c valid_command.c valid_io_redirect.c \ env.c exit.c echo.c diff --git a/headers/minishell_macro.h b/headers/minishell_macro.h index 9fbda6f..7ff7858 100644 --- a/headers/minishell_macro.h +++ b/headers/minishell_macro.h @@ -6,7 +6,7 @@ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/10/08 02:35:55 by lperrey #+# #+# */ -/* Updated: 2021/10/08 03:01:43 by lperrey ### ########.fr */ +/* Updated: 2021/10/30 22:32:48 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,4 +18,10 @@ # define PROMPT_CHEVRON "> " # define PROMPT_EURO "\001€\002 \001\b\002" +enum e_lexer_return +{ + CONTINUE_TOKEN = 1, + DELIMITE_TOKEN +}; + #endif diff --git a/srcs/lexing.c b/srcs/lexing.c deleted file mode 100644 index 5036a54..0000000 --- a/srcs/lexing.c +++ /dev/null @@ -1,196 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* lexing.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: lperrey +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ -/* Updated: 2021/10/30 14:19:42 by lperrey ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "minishell.h" -static t_token *alloc_token(size_t content_len); -static int tokenize_input(t_token *t, char *input, size_t input_len); -static int fill_token(t_token *t, char *input, int *i, int *t_i); -static int check_operators(t_token *t, char *input, int *i, int *t_i); - -enum e_in_quote_state -{ - NOT_IN = 0, - IN_QUOTES = '\'', - IN_DQUOTES = '\"' -}; - -enum e_fill_token_return -{ - CONTINUE_TOKEN = 1, - DELIMITE_TOKEN -}; - -t_token *input_to_tokens(char *input) -{ - t_token *t_head; - t_token *t_tmp; - size_t input_len; - - input_len = ft_strlen(input); - t_head = alloc_token(input_len); - if (!t_head) - return (ft_retp_perror(NULL, "alloc_token() error")); - if (!tokenize_input(t_head, input, input_len)) - return (ft_lstclear((t_list **)&t_head, free)); - t_tmp = (t_token *)ft_lstbeforelast((t_list *)t_head); - if (t_tmp && !t_tmp->next->id) - { - ft_lstdelone((t_list *)t_tmp->next, free); - t_tmp->next = NULL; - } - return (t_head); -} - -static int tokenize_input(t_token *t, char *input, size_t input_len) -{ - int i; - int t_i; - - i = 0; - t_i = 0; - while (input[i]) - { - if (fill_token(t, input, &i, &t_i) == DELIMITE_TOKEN && input[i] && t_i) - { - if (!t->id) - t->id = T_WORD; - t->next = alloc_token(input_len - i); - if (!t->next) - return (ft_reti_perror(0, "alloc_token() error")); - t = t->next; - t_i = 0; - } - } - if (!t->id && t_i) - t->id = T_WORD; - return (1); -} - -static int fill_token(t_token *t, char *input, int *i, int *t_i) -{ - static int in_quotes = 0; - - // operators - if (!in_quotes) - { - if (check_operators(t, input, i, t_i) == DELIMITE_TOKEN) - return (DELIMITE_TOKEN); - } - // quoting - if (input[*i] == '\'' && in_quotes != IN_DQUOTES) - { - t->content[(*t_i)++] = input[(*i)++]; - if (in_quotes == IN_QUOTES) - in_quotes = 0; - else if (ft_strchr(&input[*i], '\'')) // if closed quotes - in_quotes = IN_QUOTES; - return (CONTINUE_TOKEN); - } - else if (input[*i] == '\"' && in_quotes != IN_QUOTES) - { - t->content[(*t_i)++] = input[(*i)++]; - if (in_quotes == IN_DQUOTES) - in_quotes = 0; - else if (ft_strchr(&input[*i], '\"')) // if closed dquotes - in_quotes = IN_DQUOTES; - return (CONTINUE_TOKEN); - } - // blanks - if (!in_quotes && (input[*i] == ' ' || input[*i] == '\t')) - { - while (input[*i] == ' ' || input[*i] == '\t') - (*i)++; - return (DELIMITE_TOKEN); - } - else - t->content[(*t_i)++] = input[(*i)++]; - return (CONTINUE_TOKEN); -} - -static int check_operators(t_token *t, char *input, int *i, int *t_i) -{ - if (*t_i != 0 && (input[*i] == '|' || input[*i] == '<' || input[*i] == '>')) - return (DELIMITE_TOKEN); - if (input[*i] == '|') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_PIPE; - return (DELIMITE_TOKEN); - } - else if (input[*i] == '<') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_LESS; - if (input[*i] == '<') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_DLESS; - } - return (DELIMITE_TOKEN); - } - else if (input[*i] == '>') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_GREAT; - if (input[*i] == '>') - { - t->content[(*t_i)++] = input[(*i)++]; - t->id = T_DGREAT; - } - return (DELIMITE_TOKEN); - } - return (CONTINUE_TOKEN); -} - -static t_token *alloc_token(size_t content_len) -{ - t_token *token; - - token = ft_calloc(1, sizeof *token); - if (!token) - return (NULL); - token->content = ft_calloc(content_len + 1, 1); - if (!token->content) - return (ft_retp_free(NULL, token, free)); - return (token); -} - -/* -https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03 -1 - OK -2 - OK -3 - OK -4 - OK -5 - OK / SEMI-OSEF -6 - OK -7 - OK -8 - OK -9 - OSEF -10 - OK - -*/ - -// Doublon avec ft_lstclear() -/* void *free_tokens(t_token *t) -{ - void *tmp; - - while (t) - { - if (t->content) - free (t->content); - tmp = t; - t = t->next; - free(tmp); - } - return (NULL); -} */ diff --git a/srcs/lexing/check_operators.c b/srcs/lexing/check_operators.c new file mode 100644 index 0000000..1a73014 --- /dev/null +++ b/srcs/lexing/check_operators.c @@ -0,0 +1,65 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* check_operators.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ +/* Updated: 2021/10/30 22:37:08 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +static int check_redirection(t_token *t, char *input, int *i, int *t_i); +static int check_pipe(t_token *t, char *input, int *i, int *t_i); + +int check_operators(t_token *t, char *input, int *i, int *t_i) +{ + if (*t_i != 0 && (input[*i] == '|' || input[*i] == '<' || input[*i] == '>')) + return (DELIMITE_TOKEN); + else if (check_pipe(t, input, i, t_i)) + return (DELIMITE_TOKEN); + else if (check_redirection(t, input, i, t_i)) + return (DELIMITE_TOKEN); + return (CONTINUE_TOKEN); +} + +static int check_pipe(t_token *t, char *input, int *i, int *t_i) +{ + if (input[*i] == '|') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_PIPE; + return (1); + } + return (0); +} + +static int check_redirection(t_token *t, char *input, int *i, int *t_i) +{ + if (input[*i] == '<') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_LESS; + if (input[*i] == '<') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_DLESS; + } + return (1); + } + else if (input[*i] == '>') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_GREAT; + if (input[*i] == '>') + { + t->content[(*t_i)++] = input[(*i)++]; + t->id = T_DGREAT; + } + return (1); + } + return (0); +} diff --git a/srcs/lexing/fill_token.c b/srcs/lexing/fill_token.c new file mode 100644 index 0000000..8431139 --- /dev/null +++ b/srcs/lexing/fill_token.c @@ -0,0 +1,77 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* fill_token.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ +/* Updated: 2021/10/30 22:35:01 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +int check_operators(t_token *t, char *input, int *i, int *t_i); + +enum e_in_quote_state +{ + NOT_IN = 0, + IN_QUOTES = '\'', + IN_DQUOTES = '\"' +}; + +int fill_token(t_token *t, char *input, int *i, int *t_i) +{ + static int in_quotes = 0; + + // operators + if (!in_quotes) + { + if (check_operators(t, input, i, t_i) == DELIMITE_TOKEN) + return (DELIMITE_TOKEN); + } + // quoting + if (input[*i] == '\'' && in_quotes != IN_DQUOTES) + { + t->content[(*t_i)++] = input[(*i)++]; + if (in_quotes == IN_QUOTES) + in_quotes = 0; + else if (ft_strchr(&input[*i], '\'')) // if closed quotes + in_quotes = IN_QUOTES; + return (CONTINUE_TOKEN); + } + else if (input[*i] == '\"' && in_quotes != IN_QUOTES) + { + t->content[(*t_i)++] = input[(*i)++]; + if (in_quotes == IN_DQUOTES) + in_quotes = 0; + else if (ft_strchr(&input[*i], '\"')) // if closed dquotes + in_quotes = IN_DQUOTES; + return (CONTINUE_TOKEN); + } + // blanks + if (!in_quotes && (input[*i] == ' ' || input[*i] == '\t')) + { + while (input[*i] == ' ' || input[*i] == '\t') + (*i)++; + return (DELIMITE_TOKEN); + } + else + t->content[(*t_i)++] = input[(*i)++]; + return (CONTINUE_TOKEN); +} + +/* +https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03 +1 - OK +2 - OK +3 - OK +4 - OK +5 - OK / SEMI-OSEF +6 - OK +7 - OK +8 - OK +9 - OSEF +10 - OK + +*/ diff --git a/srcs/lexing/lexing.c b/srcs/lexing/lexing.c new file mode 100644 index 0000000..e089544 --- /dev/null +++ b/srcs/lexing/lexing.c @@ -0,0 +1,76 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* lexing.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: lperrey +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2021/10/19 08:38:55 by lperrey #+# #+# */ +/* Updated: 2021/10/30 22:37:48 by lperrey ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" +int fill_token(t_token *t, char *input, int *i, int *t_i); + +static t_token *alloc_token(size_t content_len); +static int tokenize_input(t_token *t, char *input, size_t input_len); + +t_token *input_to_tokens(char *input) +{ + t_token *t_head; + t_token *t_tmp; + size_t input_len; + + input_len = ft_strlen(input); + t_head = alloc_token(input_len); + if (!t_head) + return (ft_retp_perror(NULL, "alloc_token() error")); + if (!tokenize_input(t_head, input, input_len)) + return (ft_lstclear((t_list **)&t_head, free)); + t_tmp = (t_token *)ft_lstbeforelast((t_list *)t_head); + if (t_tmp && !t_tmp->next->id) + { + ft_lstdelone((t_list *)t_tmp->next, free); + t_tmp->next = NULL; + } + return (t_head); +} + +static t_token *alloc_token(size_t content_len) +{ + t_token *token; + + token = ft_calloc(1, sizeof *token); + if (!token) + return (NULL); + token->content = ft_calloc(content_len + 1, 1); + if (!token->content) + return (ft_retp_free(NULL, token, free)); + return (token); +} + +static int tokenize_input(t_token *t, char *input, size_t input_len) +{ + int i; + int t_i; + + i = 0; + t_i = 0; + while (input[i]) + { + if (fill_token(t, input, &i, &t_i) == DELIMITE_TOKEN && input[i] && t_i) + { + if (!t->id) + t->id = T_WORD; + t->next = alloc_token(input_len - i); + if (!t->next) + return (ft_reti_perror(0, "alloc_token() error")); + t = t->next; + t_i = 0; + } + } + if (!t->id && t_i) + t->id = T_WORD; + return (1); +} From 22d4bbfdd00c3302ed2495228b624ba50aa4c9c8 Mon Sep 17 00:00:00 2001 From: LuckyLaszlo Date: Sun, 31 Oct 2021 01:10:57 +0200 Subject: [PATCH 4/4] norme --- headers/minishell.h | 10 +++++++--- headers/minishell_prototypes.h | 6 +++--- headers/minishell_structs.h | 11 ++++++----- srcs/init.c | 6 +++--- srcs/lexing/fill_token.c | 1 + srcs/lexing/lexing.c | 5 +++-- srcs/parsing/valid_command.c | 1 + srcs/parsing/valid_pipeline.c | 1 + srcs/parsing/valid_syntax.c | 3 ++- 9 files changed, 27 insertions(+), 17 deletions(-) diff --git a/headers/minishell.h b/headers/minishell.h index 4ff4d89..51eecc0 100644 --- a/headers/minishell.h +++ b/headers/minishell.h @@ -27,13 +27,17 @@ # include # include # include -# include // sudo apt install libncurses-dev (OR libncurses5-dev) + +// sudo apt install libncurses-dev (OR libncurses5-dev) +# include # include -# include -# include // sudo apt install libreadline-dev +// sudo apt install libreadline-dev +# include # include +# include + # include "minishell_structs.h" # include "minishell_macro.h" # include "minishell_term_colors.h" diff --git a/headers/minishell_prototypes.h b/headers/minishell_prototypes.h index 3b491b5..db71f50 100644 --- a/headers/minishell_prototypes.h +++ b/headers/minishell_prototypes.h @@ -16,10 +16,10 @@ // Init int init(t_all *c, char *envp[]); int set_signals_handling(struct sigaction *ori_signal_behaviour, - struct sigaction *signal_behaviour); + struct sigaction *signal_behaviour); int set_terminal_attributes(struct termios *ori_termios, - struct termios *interactive_termios, - int *termios_changed); + struct termios *interactive_termios, + int *termios_changed); // Shell modes void shell_loop(t_all *c); diff --git a/headers/minishell_structs.h b/headers/minishell_structs.h index c5ba834..84f4fc6 100644 --- a/headers/minishell_structs.h +++ b/headers/minishell_structs.h @@ -13,8 +13,7 @@ #ifndef MINISHELL_STRUCTS_H # define MINISHELL_STRUCTS_H -struct s_all; -struct s_all *g_all; +struct s_all *g_all; enum e_token_id { @@ -22,10 +21,12 @@ enum e_token_id T_LESS = '<', T_GREAT = '>', T_PIPE = '|', - T_DLESS, //'<<' - T_DGREAT, //'>>' + T_DLESS, + T_DGREAT, T_WORD }; +// T_DLESS == '<<' +// T_DGREAT == '>>' typedef struct s_token { @@ -34,7 +35,7 @@ typedef struct s_token enum e_token_id id; } t_token; -typedef int (*t_builtin_ptr)(int,char **,struct s_all *); +typedef int (*t_builtin_ptr)(int,char **,struct s_all *); typedef struct s_cmd { diff --git a/srcs/init.c b/srcs/init.c index 26f826e..eda8db9 100644 --- a/srcs/init.c +++ b/srcs/init.c @@ -15,10 +15,10 @@ static char *init_prompt_base(void); static char *init_prompt(char *prompt_base); -int init(t_all *c, char *envp[]) +int init(t_all *c, char *envp[]) { g_all = c; - ft_bzero(c, sizeof *c); + ft_bzero(c, sizeof (*c)); c->envp = ft_dup_2d_char_arr(envp); if (!c->envp) return (ft_reti_perror(0, "ft_dup_2d_char_arr(envp) error")); @@ -32,7 +32,7 @@ int init(t_all *c, char *envp[]) if (isatty(STDIN_FILENO)) { if (!set_terminal_attributes(&c->ori_termios, &c->interactive_termios, - &c->termios_changed)) + &c->termios_changed)) return (ft_reti_perror(0, "set_terminal_attributes() error")); } return (1); diff --git a/srcs/lexing/fill_token.c b/srcs/lexing/fill_token.c index 8431139..4367689 100644 --- a/srcs/lexing/fill_token.c +++ b/srcs/lexing/fill_token.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + int check_operators(t_token *t, char *input, int *i, int *t_i); enum e_in_quote_state diff --git a/srcs/lexing/lexing.c b/srcs/lexing/lexing.c index e089544..33ebd56 100644 --- a/srcs/lexing/lexing.c +++ b/srcs/lexing/lexing.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + int fill_token(t_token *t, char *input, int *i, int *t_i); static t_token *alloc_token(size_t content_len); @@ -21,7 +22,7 @@ t_token *input_to_tokens(char *input) t_token *t_head; t_token *t_tmp; size_t input_len; - + input_len = ft_strlen(input); t_head = alloc_token(input_len); if (!t_head) @@ -41,7 +42,7 @@ static t_token *alloc_token(size_t content_len) { t_token *token; - token = ft_calloc(1, sizeof *token); + token = ft_calloc(1, sizeof (*token)); if (!token) return (NULL); token->content = ft_calloc(content_len + 1, 1); diff --git a/srcs/parsing/valid_command.c b/srcs/parsing/valid_command.c index 4c30f2e..eafb625 100644 --- a/srcs/parsing/valid_command.c +++ b/srcs/parsing/valid_command.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + int valid_io_redirect(t_token **token_list); static int valid_command_rule1(t_token **token_list); diff --git a/srcs/parsing/valid_pipeline.c b/srcs/parsing/valid_pipeline.c index cda0454..e003d29 100644 --- a/srcs/parsing/valid_pipeline.c +++ b/srcs/parsing/valid_pipeline.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + int valid_command(t_token **token_list); int valid_pipeline(t_token **token_list) diff --git a/srcs/parsing/valid_syntax.c b/srcs/parsing/valid_syntax.c index 0fd9f2f..0254712 100644 --- a/srcs/parsing/valid_syntax.c +++ b/srcs/parsing/valid_syntax.c @@ -11,6 +11,7 @@ /* ************************************************************************** */ #include "minishell.h" + int valid_pipeline(t_token **token_list); int valid_syntax(t_token *token_list) @@ -18,7 +19,7 @@ int valid_syntax(t_token *token_list) if (valid_pipeline(&token_list)) return (1); else - { // WIP ERROR + { ft_putstr_fd("minishell: syntax error near unexpected token \'", 2); ft_putstr_fd(token_list->content, 2); ft_putstr_fd("\'\n", 2);