From 22403b127ecab92fe9e199d96b6676f7ce589e54 Mon Sep 17 00:00:00 2001 From: Tom Moron Date: Fri, 9 Feb 2024 14:42:03 +0100 Subject: [PATCH] variables d'environnement dans le parsing --- Makefile | 8 +- ft_echo.c | 35 +++++++ ft_exec.c | 37 +++++++ ft_exit.c | 31 ++++++ ft_lst_cmd.c | 11 ++- ft_lst_env.c | 54 +++++++++++ libft/ft_itoa.c | 4 +- libft/ft_strlen.c | 4 +- libft/libft.h | 3 +- main.c | 212 ++++++++++++++++++++++++++++++++--------- minishell.h | 19 +++- test.c => other/test.c | 4 +- other/test2.c | 19 ++++ 13 files changed, 382 insertions(+), 59 deletions(-) create mode 100644 ft_echo.c create mode 100644 ft_exec.c create mode 100644 ft_exit.c create mode 100644 ft_lst_env.c rename test.c => other/test.c (91%) create mode 100644 other/test2.c diff --git a/Makefile b/Makefile index db2b350..d3c885d 100755 --- a/Makefile +++ b/Makefile @@ -6,14 +6,18 @@ # By: tomoron +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2023/07/28 00:35:01 by tomoron #+# #+# # -# Updated: 2024/02/06 22:07:47 by tomoron ### ########.fr # +# Updated: 2024/02/08 16:18:42 by tomoron ### ########.fr # # # # **************************************************************************** # CC = cc SRCS = main.c\ - ft_lst_cmd.c + ft_lst_cmd.c\ + ft_lst_env.c\ + ft_exec.c\ + ft_exit.c\ + ft_echo.c OBJS = $(SRCS:.c=.o) diff --git a/ft_echo.c b/ft_echo.c new file mode 100644 index 0000000..2f9530d --- /dev/null +++ b/ft_echo.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_echo.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/07 15:30:37 by tomoron #+# #+# */ +/* Updated: 2024/02/07 23:15:04 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int ft_echo(t_cmd *args) +{ + int put_nl; + + put_nl = 1; + while(args && !strcmp(args->token,"-n")) + { + put_nl = 0; + args = args->next; + } + while(args) + { + ft_putstr_fd(args->token, STDOUT_FILENO); + if(args->next) + ft_putchar_fd(' ',STDOUT_FILENO); + args = args->next; + } + if(put_nl) + ft_putchar_fd('\n',STDOUT_FILENO); + return(0); +} diff --git a/ft_exec.c b/ft_exec.c new file mode 100644 index 0000000..caf1614 --- /dev/null +++ b/ft_exec.c @@ -0,0 +1,37 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_exec.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/07 14:12:49 by tomoron #+# #+# */ +/* Updated: 2024/02/08 16:57:26 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +int exec_builtin(t_cmd *parsed_cmd, t_env *env) +{ + if(!strcmp(parsed_cmd->token, "echo")) + g_return_code = ft_echo(parsed_cmd->next); + else if (!strcmp(parsed_cmd->token,"ret")) + g_return_code = ft_atoi(parsed_cmd->next->token); + else if(!strcmp(parsed_cmd->token, "env")) + g_return_code = ft_print_env(env); + else if(!strcmp(parsed_cmd->token, "exit")) + ft_exit(parsed_cmd); + else + return(STDIN_FILENO); + return(STDOUT_FILENO); +} + +void ft_exec_command(t_cmd *parsed_cmd, t_env *env) +{ + if(!parsed_cmd) + return; + if(exec_builtin(parsed_cmd, env)) + return ; + ft_printf("not a builtin\n"); +} diff --git a/ft_exit.c b/ft_exit.c new file mode 100644 index 0000000..3c95749 --- /dev/null +++ b/ft_exit.c @@ -0,0 +1,31 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_exit.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/07 16:04:11 by tomoron #+# #+# */ +/* Updated: 2024/02/07 16:48:07 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +void ft_exit(t_cmd *args) +{ + t_cmd *start; + + start = args; + args = args->next; + ft_printf("exit\n"); + if(args && args->next) + ft_printf("minishell: exit: too many arguments\n"); + else + { + ft_free_cmd(start); + if(args) + exit((unsigned char)ft_atoi(args->token)); + exit(g_return_code); + } +} diff --git a/ft_lst_cmd.c b/ft_lst_cmd.c index ecfc2fd..d89719c 100644 --- a/ft_lst_cmd.c +++ b/ft_lst_cmd.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/02/06 20:46:19 by tomoron #+# #+# */ -/* Updated: 2024/02/06 22:09:09 by tomoron ### ########.fr */ +/* Updated: 2024/02/08 12:42:12 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,3 +29,12 @@ t_cmd *ft_cmd_add_back(t_cmd *cmd, char *token) current->next = res; return (cmd); } + +void ft_free_cmd(t_cmd *cmd) +{ + if(cmd && cmd->next) + ft_free_cmd(cmd->next); + if(cmd) + free(cmd->token); + free(cmd); +} diff --git a/ft_lst_env.c b/ft_lst_env.c new file mode 100644 index 0000000..8215094 --- /dev/null +++ b/ft_lst_env.c @@ -0,0 +1,54 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* ft_lst_env.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/06 20:46:19 by tomoron #+# #+# */ +/* Updated: 2024/02/08 16:58:48 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "minishell.h" + +t_env *ft_env_add_back(t_env *env, char *name, char *value) +{ + t_env *res; + t_env *current; + + res = ft_calloc(1, sizeof(t_env)); + if (!res) + return (env); + res->name = name; + res->value = value; + if (!env) + return (res); + current = env; + while (current->next) + current = current->next; + current->next = res; + return (env); +} + +void ft_free_env(t_env *env) +{ + if(env && env->next) + ft_free_env(env->next); + if(env) + { + free(env->name); + free(env->value); + } + free(env); +} + +int ft_print_env(t_env *env) +{ + while(env) + { + printf("%s=%s\n",env->name, env->value); + env = env->next; + } + return(0); +} diff --git a/libft/ft_itoa.c b/libft/ft_itoa.c index e076598..a08f492 100755 --- a/libft/ft_itoa.c +++ b/libft/ft_itoa.c @@ -6,13 +6,13 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/01 02:36:12 by tomoron #+# #+# */ -/* Updated: 2023/11/02 10:16:45 by tomoron ### ########.fr */ +/* Updated: 2024/02/08 13:56:37 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "libft.h" -static int get_number_len(long int n) +int get_number_len(long int n) { int res; diff --git a/libft/ft_strlen.c b/libft/ft_strlen.c index 0e7d7dc..59391b3 100755 --- a/libft/ft_strlen.c +++ b/libft/ft_strlen.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/30 12:34:41 by tomoron #+# #+# */ -/* Updated: 2023/10/31 14:53:10 by tomoron ### ########.fr */ +/* Updated: 2024/02/08 17:54:36 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ #include "libft.h" @@ -16,7 +16,7 @@ size_t ft_strlen(const char *str) unsigned int n; n = 0; - while (str[n]) + while (str && str[n]) n++; return (n); } diff --git a/libft/libft.h b/libft/libft.h index 41f78aa..4932fe5 100755 --- a/libft/libft.h +++ b/libft/libft.h @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/10/30 16:55:48 by tomoron #+# #+# */ -/* Updated: 2024/02/06 22:15:58 by tomoron ### ########.fr */ +/* Updated: 2024/02/08 18:44:22 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -60,6 +60,7 @@ char *ft_strdup(const char *src); void ft_bzero(void *s, size_t n); void ft_putnbr_fd(int n, int fd); void ft_free_str_arr(char **arr); +int get_number_len(long int n); size_t ft_strlen(const char *str); void ft_swap(int *n1, int *n2); t_list *ft_lstnew(void *content); diff --git a/main.c b/main.c index b2c36d5..03e7cd9 100644 --- a/main.c +++ b/main.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/02/02 21:59:20 by tomoron #+# #+# */ -/* Updated: 2024/02/06 22:21:44 by tomoron ### ########.fr */ +/* Updated: 2024/02/09 14:37:48 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -23,10 +23,62 @@ char *get_prompt(void) res = ft_strjoin_free(res, getenv("USER"),1); res = ft_strjoin_free(res, "@",1); res = ft_strjoin_free(res, "minishell \001\033[0m\002$>",1); + return (res); +} + +char *ft_getenv(t_env *env, char *name) +{ + while(env) + { + if(!ft_strcmp(env->name, name)) + return(env->value); + env = env->next; + } + return(0); +} + +int get_var_name_len(char *command) +{ + int res; + + res = 0; + if(command[res] == '?') + return(1); + while(ft_isalnum(command[res]) || command[res] == '_') + res++; return(res); } -int ft_get_token_len(char *command) +char *get_var_name(char *command) +{ + char *res; + int len; + + len = get_var_name_len(command); + res = ft_substr(command,0, len); + return(res); +} + +int ft_get_var_len(char **command, t_env *env) +{ + char *var_name; + char *env_var; + + (*command)++; + if (!ft_isalnum(**command) && **command != '_' && **command != '?') + return (1); + if (**command == '?') + return (get_number_len(g_return_code)); + var_name = get_var_name(*command); + env_var = ft_getenv(env, var_name); + free(var_name); + if (!env_var) + return (0); + *command += get_var_name_len(*command) - 1; + return (ft_strlen(env_var)); +} + +int ft_get_token_len(char *command, t_env *env) { int in_quote; int in_dquote; @@ -35,94 +87,160 @@ int ft_get_token_len(char *command) in_quote = 0; in_dquote = 0; res = 0; - while(*command && (!isspace(*command) || in_quote || in_dquote)) + while (*command && (!ft_isspace(*command) || in_quote || in_dquote)) { - if(*command == '"' && !in_quote) + if (*command == '"' && !in_quote) in_dquote = !in_dquote; - if(*command == '\'' && !in_dquote) + if (*command == '\'' && !in_dquote) in_quote = !in_quote; - if(*command != '\'' && *command != '"') + if (*command == '$' && !in_quote) + res += ft_get_var_len(&command, env); + else if (*command != '\'' && *command != '"') res++; - if((*command == '\'' && in_dquote) || (*command == '"' && in_quote)) + else if ((*command == '\'' && in_dquote) || (*command == '"' && in_quote)) res++; command++; } - return(res); + return (res); } -void ft_skip_spaces(char **command) +int ft_add_var_to_str(char *res, char **command, t_env *env) { - while (ft_isspace(**command)) - (*command)++; + char *var_name; + char *var; + int i; + + i = -1; + if (!ft_isalnum(**command) && **command != '_' && **command != '?') + { + *res = '$'; + return(1); + } + if (**command == '?') + { + var = ft_itoa(g_return_code); + while(var && var[++i]) + res[i] = var[i]; + free(var); + return(i + 1); + } + var_name = get_var_name(*command); + var = ft_getenv(env, var_name); + free(var_name); + while(var && var[++i]) + res[i] = var[i]; + *command += get_var_name_len(*command) - 1; + return (i + !var); } -char *ft_get_token(char **command) +char *ft_get_token(char **command, int *in_quote, int *in_dquote, t_env *env) { - int in_quote; - int in_dquote; char *res; int i; - in_quote = 0; - in_dquote = 0; i = 0; while (ft_isspace(**command)) (*command)++; - res = malloc(ft_get_token_len(*command)); - while(res && **command && (!isspace(**command) || in_quote || in_dquote)) + res = ft_calloc(ft_get_token_len(*command, env) + 1, 1); + while (res && **command && (!ft_isspace(**command) || *in_quote || *in_dquote)) { - if(**command == '"' && !in_quote) - in_dquote = !in_dquote; - if(**command == '\'' && !in_dquote) - in_quote = !in_quote; - if(((**command == '\'' && in_dquote) || (**command == '"' && in_quote)) + if (**command == '"' && !*in_quote) + *in_dquote = !*in_dquote; + if (**command == '\'' && !*in_dquote) + *in_quote = !*in_quote; + if (**command == '$' && !*in_quote) + { + (*command)++; + i += ft_add_var_to_str(res + i, command , env); + } + else if (((**command == '\'' && *in_dquote) || (**command == '"' && *in_quote)) || (**command != '\'' && **command != '"')) res[i++] = **command; (*command)++; } - return(res); + return (res); } -t_cmd *ft_parse_command(char *command) +t_cmd *ft_parse_command(char *command, t_env *env) { + int in_quote; + int in_dquote; t_cmd *res; char *token; - res = 0; - while(*command) + in_quote = 0; + in_dquote = 0; + res = STDIN_FILENO; + if (!command) + return (STDIN_FILENO); + while (*command) { - token = ft_get_token(&command); + token = ft_get_token(&command, &in_quote, &in_dquote, env); res = ft_cmd_add_back(res, token); } - return(res); + if (in_quote || in_dquote) + { + ft_free_cmd(res); + ft_putstr_fd("minishell: syntax error\n", 2); + return (0); + } + return (res); } -int main(void) +t_env *ft_get_env(char **envp) +{ + t_env *env; + char *name; + char *value; + int i; + int j; + + env = 0; + while (*envp) + { + i = 0; + j = 0; + while ((*envp)[i] && (*envp)[i] != '=') + i++; + while ((*envp)[i + 1 + j]) + j++; + name = ft_substr(*envp, 0, i); + value = ft_substr(*envp, i + 1, j); + env = ft_env_add_back(env, name, value); + if (!name || !value) + ft_free_env(env); + if (!name || !value) + return (0); + envp++; + } + return (env); +} + +int main(int argc, char **argv, char **envp) { char *command; + t_cmd *parsed_cmd; + t_env *env; char *prompt; - command = (char *)1; - while(command) + command = (char *)STDOUT_FILENO; + (void)argc; + (void)argv; + env = ft_get_env(envp); + while (env && command) { prompt = get_prompt(); - if(!prompt) - exit(0); + if (!prompt) + exit(STDIN_FILENO); command = readline(prompt); - add_history(command); free(prompt); - t_cmd *test; - test = ft_parse_command(command); - printf("%s\n",test->token); - printf("%s\n",command); - if(command && !ft_strcmp(command,"exit")) - { - rl_clear_history(); - free(command); - printf("au revoir :,(\n"); - exit(0); - } - rl_clear_history(); + add_history(command); + parsed_cmd = ft_parse_command(command, env); free(command); + ft_exec_command(parsed_cmd, env); + ft_free_cmd(parsed_cmd); } + rl_clear_history(); + ft_free_env(env); + return (g_return_code); } diff --git a/minishell.h b/minishell.h index 39879c4..c2ac5ae 100644 --- a/minishell.h +++ b/minishell.h @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/02/04 17:31:38 by tomoron #+# #+# */ -/* Updated: 2024/02/06 22:09:30 by tomoron ### ########.fr */ +/* Updated: 2024/02/08 16:58:15 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -24,6 +24,21 @@ typedef struct s_cmd struct s_cmd *next; } t_cmd; -t_cmd *ft_cmd_add_back(t_cmd *res, char *token); +typedef struct s_env +{ + char *name; + char *value; + struct s_env *next; +} t_env; +extern int g_return_code; + +t_cmd *ft_cmd_add_back(t_cmd *res, char *token); +void ft_free_cmd(t_cmd *cmd); +void ft_exec_command(t_cmd *cmd, t_env *env); +int ft_echo(t_cmd *args); +void ft_exit(t_cmd *args); +t_env *ft_env_add_back(t_env *env, char *name, char *value); +void ft_free_env(t_env *env); +int ft_print_env(t_env *env); #endif diff --git a/test.c b/other/test.c similarity index 91% rename from test.c rename to other/test.c index 720385a..f5a77a2 100644 --- a/test.c +++ b/other/test.c @@ -6,7 +6,7 @@ /* By: tomoron +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/02/04 17:30:08 by tomoron #+# #+# */ -/* Updated: 2024/02/06 12:41:57 by tomoron ### ########.fr */ +/* Updated: 2024/02/07 14:29:12 by tomoron ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,7 +18,7 @@ int main(int argc, char **argv) int i = 0; while(i < argc) { - printf("%s\n",argv[i]); + printf("\"%s\"\n",argv[i]); i++; } return(0); diff --git a/other/test2.c b/other/test2.c new file mode 100644 index 0000000..c07b453 --- /dev/null +++ b/other/test2.c @@ -0,0 +1,19 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* test2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: tomoron +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/02/07 13:30:04 by tomoron #+# #+# */ +/* Updated: 2024/02/07 13:34:55 by tomoron ### ########.fr */ +/* */ +/* ************************************************************************** */ +#include +#include +int main(int argc,char **argv) +{ + if(argc == 2) + return(atoi(argv[1])); + return(0); +}