diff --git a/Makefile b/Makefile index 42777f6..c81a0d7 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ # By: ttsubo +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2025/04/03 12:55:20 by ttsubo #+# #+# # -# Updated: 2025/05/02 14:33:45 by ttsubo ### ########.fr # +# Updated: 2025/05/02 22:01:21 by ttsubo ### ########.fr # # # # **************************************************************************** # @@ -53,8 +53,9 @@ INVOKE_CMD_SRC = create_envp.c exec_pipeline.c execute_cmd.c \ redirect.c fds.c wait_pipeline.c TOKENIZER_SRC = tokenizer.c tokenizer_error.c read_token.c \ is_quote_closed.c get_token_capa.c is_redirect_validate.c -PARSER_SRC = allocate_cmds.c parser.c parser_utils.c setup_cmds.c \ - expand_env.c +PARSER_SRC = allocate_cmds.c parser.c parser_free.c parser_utils.c setup_cmds.c \ + allocate_cmds_utils.c allocate_cmds_utils_2.c \ + expand_env.c expand_tokens.c BUILTIN_SRC = cd.c exit.c pwd.c echo.c env.c unset.c export.c \ env_utils.c env_utils_2.c env_utils_3.c builtin_utils.c \ export_exec.c export_print_sorted_env.c export_error.c split_key_value.c diff --git a/inc/parser.h b/inc/parser.h index fb46d8d..46c39aa 100644 --- a/inc/parser.h +++ b/inc/parser.h @@ -6,7 +6,7 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/21 14:14:59 by ttsubo #+# #+# */ -/* Updated: 2025/04/29 12:17:18 by ttsubo ### ########.fr */ +/* Updated: 2025/05/02 21:25:06 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,15 +14,24 @@ # define PARSER_H # include "cmd.h" -# include "libft.h" +# include "parser_free.h" # include "expand_env.h" +# include "libft.h" + +size_t count_cmds(char **tokens); +char **next_cmd_start(char **token_ptr); +t_cmd **calloc_cmds(char **tokens); +t_cmd *calloc_cmd(void); +char **calloc_argv(char **tokens); +char *calloc_arg(char *token); t_cmd **parser(char **tokens, t_minish *minish); +char **expand_tokens(char **tokens, t_minish *minish); void set_cmd_type(t_cmd *cmd, char *token); size_t cmds_len(t_cmd **cmds); +size_t count_args_until_separator(char **tokens); int is_separator(char *token); -void free_cmds(t_cmd **cmds, size_t count); t_cmd **allocate_cmds(char **tokens); -t_cmd **setup_cmds(t_cmd **cmds, char **tokens, t_minish *minish); +t_cmd **setup_cmds(t_cmd **cmds, char **tokens); #endif \ No newline at end of file diff --git a/inc/parser_free.h b/inc/parser_free.h new file mode 100644 index 0000000..dbd2fe4 --- /dev/null +++ b/inc/parser_free.h @@ -0,0 +1,20 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_free.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ttsubo +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/05/02 21:22:56 by ttsubo #+# #+# */ +/* Updated: 2025/05/02 21:27:46 by ttsubo ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef PARSER_FREE_H +# define PARSER_FREE_H + +void free_tokens(char **tokens); +void free_cmd(t_cmd *cmd); +void free_cmds(t_cmd **cmds); + +#endif \ No newline at end of file diff --git a/src/main.c b/src/main.c index d3307c7..95e9423 100644 --- a/src/main.c +++ b/src/main.c @@ -3,10 +3,10 @@ /* ::: :::::::: */ /* main.c :+: :+: :+: */ /* +:+ +:+ +:+ */ -/* By: dayano +#+ +:+ +#+ */ +/* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/03 12:50:11 by ttsubo #+# #+# */ -/* Updated: 2025/04/29 13:06:39 by dayano ### ########.fr */ +/* Updated: 2025/05/02 21:25:49 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ @@ -61,7 +61,7 @@ static bool prompt(char *program_name, t_minish *minish) if (cmds[0]->argc > 0) minish->last_status = invoke_commands(cmds[0], minish); _free_tokens(tokens); - free_cmds(cmds, cmds_len(cmds)); + free_cmds(cmds); free(line); return (true); } @@ -70,6 +70,7 @@ int main(int argc, char **argv, char **envp) { t_minish *minish; char *program_name; + int last_status; (void)argc; program_name = argv[0]; @@ -77,6 +78,7 @@ int main(int argc, char **argv, char **envp) minish_signal(); while (prompt(program_name, minish)) ; + last_status = minish->last_status; destroy_minish(minish); - return (minish->last_status); + return (last_status); } diff --git a/src/parser/allocate_cmds.c b/src/parser/allocate_cmds.c index db73bf7..36dab42 100644 --- a/src/parser/allocate_cmds.c +++ b/src/parser/allocate_cmds.c @@ -6,56 +6,71 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 12:19:28 by ttsubo #+# #+# */ -/* Updated: 2025/04/26 20:39:41 by ttsubo ### ########.fr */ +/* Updated: 2025/05/02 21:26:21 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ #include "parser.h" -static size_t _count_cmds(char **tokens) +static int _allocate_argv(t_cmd *cmd, char **token_ptr) { - size_t i; - size_t cmd_count; + size_t arg_i; + size_t len; - i = 0; - cmd_count = 1; - while (tokens[i]) + cmd->argv = calloc_argv(token_ptr); + if (!cmd->argv) + return (1); + arg_i = 0; + len = count_args_until_separator(token_ptr); + while (arg_i < len) { - if (is_separator(tokens[i])) - cmd_count++; - i++; + cmd->argv[arg_i] = calloc_arg(token_ptr[arg_i]); + if (!cmd->argv[arg_i]) + { + while (0 < arg_i) + free(cmd->argv[--arg_i]); + free(cmd->argv); + return (1); + } + arg_i++; } - return (cmd_count); + return (0); } -static t_cmd **_allocate_cmds(size_t count) +static t_cmd *_allocate_cmd(char **token_ptr) { - size_t i; - t_cmd **cmds; + t_cmd *cmd; - i = 0; - cmds = ft_calloc(count + 1, sizeof(t_cmd *)); - if (!cmds) + cmd = calloc_cmd(); + if (!cmd) return (NULL); - while (i < count) - { - cmds[i] = ft_calloc(1, sizeof(t_cmd)); - if (!cmds[i]) - return (free_cmds(cmds, i), NULL); - if (i > 0) - cmds[i - 1]->next = cmds[i]; - i++; - } - cmds[i] = NULL; - return (cmds); + if (_allocate_argv(cmd, token_ptr)) + return (free(cmd), NULL); + return (cmd); } t_cmd **allocate_cmds(char **tokens) { + char **token_ptr; t_cmd **cmds; + size_t cmd_i; + size_t len; - cmds = _allocate_cmds(_count_cmds(tokens)); + cmds = calloc_cmds(tokens); if (!cmds) return (NULL); + cmd_i = 0; + len = count_cmds(tokens); + token_ptr = tokens; + while (cmd_i < len) + { + cmds[cmd_i] = _allocate_cmd(token_ptr); + if (!cmds[cmd_i]) + return (free_cmds(cmds), NULL); + if (cmd_i > 0) + cmds[cmd_i - 1]->next = cmds[cmd_i]; + token_ptr = next_cmd_start(token_ptr); + cmd_i++; + } return (cmds); } diff --git a/src/parser/allocate_cmds_utils.c b/src/parser/allocate_cmds_utils.c new file mode 100644 index 0000000..94cdf87 --- /dev/null +++ b/src/parser/allocate_cmds_utils.c @@ -0,0 +1,63 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* allocate_cmds_utils.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ttsubo +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/24 12:19:28 by ttsubo #+# #+# */ +/* Updated: 2025/05/02 18:12:06 by ttsubo ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser.h" + +char **next_cmd_start(char **token_ptr) +{ + size_t token_i; + + token_i = 0; + while (token_ptr[token_i] && !is_separator(token_ptr[token_i])) + token_i++; + if (token_ptr[token_i]) + token_i++; + return (&token_ptr[token_i]); +} + +t_cmd **calloc_cmds(char **tokens) +{ + t_cmd **cmds; + size_t cmd_i; + size_t token_i; + + token_i = 0; + cmd_i = 1; + while (tokens[token_i]) + { + if (is_separator(tokens[token_i])) + cmd_i++; + token_i++; + } + cmds = ft_calloc(sizeof(t_cmd *), cmd_i + 1); + return (cmds); +} + +t_cmd *calloc_cmd(void) +{ + return (ft_calloc(sizeof(t_cmd), 1)); +} + +char **calloc_argv(char **tokens) +{ + size_t token_i; + + token_i = 0; + while (tokens[token_i] && !is_separator(tokens[token_i])) + token_i++; + return (ft_calloc(sizeof(char *), token_i + 1)); +} + +char *calloc_arg(char *token) +{ + return (ft_strdup(token)); +} diff --git a/src/parser/allocate_cmds_utils_2.c b/src/parser/allocate_cmds_utils_2.c new file mode 100644 index 0000000..56cc57d --- /dev/null +++ b/src/parser/allocate_cmds_utils_2.c @@ -0,0 +1,29 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* allocate_cmds_utils_2.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ttsubo +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/24 12:19:28 by ttsubo #+# #+# */ +/* Updated: 2025/05/02 16:58:45 by ttsubo ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser.h" + +size_t count_cmds(char **tokens) +{ + size_t i; + size_t count; + + i = 0; + count = 1; + while (tokens[i]) + { + if (is_separator(tokens[i])) + count++; + i++; + } + return (count); +} diff --git a/src/parser/expand_tokens.c b/src/parser/expand_tokens.c new file mode 100644 index 0000000..2bd0a83 --- /dev/null +++ b/src/parser/expand_tokens.c @@ -0,0 +1,92 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* expand_tokens.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ttsubo +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/05/02 17:08:42 by ttsubo #+# #+# */ +/* Updated: 2025/05/02 17:52:43 by ttsubo ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser.h" + +static size_t _tokens_len(char **tokens) +{ + size_t i; + + i = 0; + while (tokens[i]) + i++; + return (i); +} + +/** + * @note pre: $? in str + */ +static char *_expand_dollar(char *str, t_minish *minish) +{ + char *pre; + char *suf; + char *sts_str; + char *joined; + char *final; + + pre = ft_substr(str, 0, ft_strlen_until(str, '$')); + sts_str = ft_itoa(minish->last_status); + suf = ft_strdup(str + ft_strlen_until(str, '$') + 2); + if (!pre || !sts_str || !suf) + return (free(pre), free(sts_str), free(suf), NULL); + joined = ft_strjoin(pre, sts_str); + final = ft_strjoin(joined, suf); + return (free(pre), free(sts_str), free(suf), free(joined), final); +} + +static char *_expand(char *token, t_minish *minish) +{ + char *result; + char *tmp; + + result = ft_strdup(token); + if (!result) + return (NULL); + while (ft_strchr(result, '$')) + { + tmp = result; + if (ft_strnstr(result, "$?", ft_strlen(result))) + result = _expand_dollar(tmp, minish); + else + result = expand_env(tmp, minish); + free(tmp); + if (!result) + return (NULL); + } + return (result); +} + +char **expand_tokens(char **tokens, t_minish *minish) +{ + size_t token_i; + size_t len; + char **expanded; + + len = _tokens_len(tokens); + expanded = ft_calloc(sizeof(char *), len + 1); + if (!expanded) + return (NULL); + token_i = 0; + while (token_i < len) + { + expanded[token_i] = _expand(tokens[token_i], minish); + if (!expanded[token_i]) + { + while (0 < token_i) + free(expanded[--token_i]); + free(expanded); + return (NULL); + } + token_i++; + } + return (expanded); +} diff --git a/src/parser/parser.c b/src/parser/parser.c index c37d81d..6657ade 100644 --- a/src/parser/parser.c +++ b/src/parser/parser.c @@ -6,27 +6,32 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/21 14:14:32 by ttsubo #+# #+# */ -/* Updated: 2025/04/26 11:48:00 by ttsubo ### ########.fr */ +/* Updated: 2025/05/02 21:27:58 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ #include "parser.h" /** - * @brief - * - * @param tokens - * @return t_cmd** + * @brief + * + * @param tokens + * @return t_cmd** */ t_cmd **parser(char **tokens, t_minish *minish) { + char **expanded_tokens; t_cmd **cmds; - cmds = allocate_cmds(tokens); - if (!cmds) + expanded_tokens = expand_tokens(tokens, minish); + if (!expanded_tokens) return (NULL); - cmds = setup_cmds(cmds, tokens, minish); + cmds = allocate_cmds(expanded_tokens); if (!cmds) - return (NULL); + return (free_tokens(expanded_tokens), NULL); + cmds = setup_cmds(cmds, expanded_tokens); + if (!cmds) + return (free_tokens(expanded_tokens), NULL); + free_tokens(expanded_tokens); return (cmds); } diff --git a/src/parser/parser_free.c b/src/parser/parser_free.c new file mode 100644 index 0000000..e302337 --- /dev/null +++ b/src/parser/parser_free.c @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* parser_free.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: ttsubo +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/05/02 20:55:39 by ttsubo #+# #+# */ +/* Updated: 2025/05/02 21:28:08 by ttsubo ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "parser.h" + +void free_tokens(char **tokens) +{ + size_t token_i; + + token_i = 0; + while (tokens && tokens[token_i]) + token_i++; + while (0 < token_i) + free(tokens[--token_i]); + free(tokens); +} + +void free_cmd(t_cmd *cmd) +{ + size_t arg_i; + + arg_i = 0; + while (cmd->argv && cmd->argv[arg_i]) + free(cmd->argv[arg_i++]); + free(cmd->argv); + free(cmd); +} + +void free_cmds(t_cmd **cmds) +{ + size_t cmd_i; + + cmd_i = 0; + while (cmds[cmd_i]) + free_cmd(cmds[cmd_i++]); + free(cmds); +} diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c index 3a4adbd..49c4e7c 100644 --- a/src/parser/parser_utils.c +++ b/src/parser/parser_utils.c @@ -6,7 +6,7 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:40:56 by ttsubo #+# #+# */ -/* Updated: 2025/04/29 12:16:53 by ttsubo ### ########.fr */ +/* Updated: 2025/05/02 21:26:41 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,32 +26,24 @@ void set_cmd_type(t_cmd *cmd, char *token) cmd->type = REDIR_NONE; } -size_t cmds_len(t_cmd **cmds) +size_t count_args_until_separator(char **tokens) { size_t i; i = 0; - while (cmds[i]) + while (tokens[i] && !is_separator(tokens[i])) i++; return (i); } -void free_cmds(t_cmd **cmds, size_t count) +size_t cmds_len(t_cmd **cmds) { - size_t cmd_i; - size_t arg_i; + size_t i; - cmd_i = 0; - while (cmd_i < count) - { - arg_i = 0; - while (cmds[cmd_i]->argv && cmds[cmd_i]->argv[arg_i]) - free(cmds[cmd_i]->argv[arg_i++]); - free(cmds[cmd_i]->argv); - free(cmds[cmd_i]); - cmd_i++; - } - free(cmds); + i = 0; + while (cmds[i]) + i++; + return (i); } int is_separator(char *token) diff --git a/src/parser/setup_cmds.c b/src/parser/setup_cmds.c index 527270d..c781b34 100644 --- a/src/parser/setup_cmds.c +++ b/src/parser/setup_cmds.c @@ -6,82 +6,12 @@ /* By: ttsubo +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/24 13:38:36 by ttsubo #+# #+# */ -/* Updated: 2025/04/29 12:56:28 by ttsubo ### ########.fr */ +/* Updated: 2025/05/02 21:26:54 by ttsubo ### ########.fr */ /* */ /* ************************************************************************** */ #include "parser.h" -static int _allocate_argv(t_cmd *cmd, char **tokens) -{ - size_t token_i; - size_t argc; - - token_i = 0; - argc = 0; - while (tokens[token_i] && !is_separator(tokens[token_i])) - { - token_i++; - argc++; - } - cmd->argv = ft_calloc(argc + 1, sizeof(char *)); - if (!cmd->argv) - return (1); - return (0); -} - -static char *_expand_dollar(char *str, t_minish *minish, size_t i) -{ - char *pre; - char *suf; - char *sts_str; - char *joined; - char *final; - - if (str[i + 1] && str[i + 1] == '?') - { - pre = ft_substr(str, 0, i); - sts_str = ft_itoa(minish->last_status); - suf = ft_strdup(str + i + 2); - if (!pre || !sts_str || !suf) - return (free(pre), free(sts_str), free(suf), NULL); - joined = ft_strjoin(pre, sts_str); - final = ft_strjoin(joined, suf); - return (free(pre), free(sts_str), free(suf), free(joined), final); - } - else - return (expand_env(str, minish)); -} - -static char *_expand_arg(char *token, t_minish *minish) -{ - size_t token_i; - bool is_squote; - char *result; - char *expanded; - - token_i = 0; - is_squote = 0; - result = ft_strdup(token); - while (result[token_i]) - { - if (result[token_i] == '\'') - is_squote = !is_squote; - if (!is_squote && result[token_i] == '$') - { - expanded = _expand_dollar(result, minish, token_i); - if (!expanded) - return (result); - free(result); - result = expanded; - token_i = 0; - continue ; - } - token_i++; - } - return (result); -} - static void _next_cmd(t_cmd **cmds, size_t *cmd_i, size_t *arg_i, char *token) { cmds[*cmd_i]->argv[*arg_i] = NULL; @@ -89,10 +19,9 @@ static void _next_cmd(t_cmd **cmds, size_t *cmd_i, size_t *arg_i, char *token) (*arg_i) = 0; (*cmd_i)++; set_cmd_type(cmds[*cmd_i], token); - _allocate_argv(cmds[*cmd_i], &token); } -t_cmd **setup_cmds(t_cmd **cmds, char **tokens, t_minish *minish) +t_cmd **setup_cmds(t_cmd **cmds, char **tokens) { size_t token_i; size_t cmd_i; @@ -102,21 +31,19 @@ t_cmd **setup_cmds(t_cmd **cmds, char **tokens, t_minish *minish) cmd_i = 0; arg_i = 0; set_cmd_type(cmds[0], tokens[token_i]); - _allocate_argv(cmds[0], tokens); while (tokens[token_i]) { if (is_separator(tokens[token_i])) _next_cmd(cmds, &cmd_i, &arg_i, tokens[token_i]); else { - cmds[cmd_i]->argv[arg_i] = _expand_arg(tokens[token_i], minish); + cmds[cmd_i]->argv[arg_i] = ft_strdup(tokens[token_i]); if (!cmds[cmd_i]->argv[arg_i]) - return (free_cmds(cmds, cmds_len(cmds)), NULL); + return (free_cmds(cmds), NULL); arg_i++; } token_i++; } cmds[cmd_i]->argc = arg_i; - cmds[++cmd_i] = NULL; return (cmds); }