diff --git a/Makefile b/Makefile index 8d859e5..ec182c8 100644 --- a/Makefile +++ b/Makefile @@ -33,6 +33,7 @@ srcs = \ src/parser/cmdgroup/cmdgroup.c \ src/parser/command_list/command_list_builder.c \ src/parser/command_list/command_list.c \ + src/parser/command_list/command_list_item.c \ src/parser/command_list/operator.c \ src/parser/matchers/blank.c \ src/parser/matchers/identifier.c \ diff --git a/NOTES.md b/NOTES.md index 9ccb65b..75a3ec5 100644 --- a/NOTES.md +++ b/NOTES.md @@ -208,22 +208,22 @@ not remain in effect after the subshell completes. The exit status of this construct is the exit status of LIST. ```c -typedef enum e_cmdgroup_item_type +typedef enum e_cmdlist_item_type { TYPE_INVALID, TYPE_CMDGROUP, TYPE_PIPELINE, -} t_cmdgroup_item_type; +} t_cmdlist_item_type; typedef struct s_cmdlist_item { - enum e_cmdgroup_item_type type; - union u_cmdgroup_item_inner + enum e_cmdlist_item_type type; + union u_cmdlist_item_inner { t_cmdgroup *cmdgroup; struct s_pipeline *pipeline; } inner; -} t_cmdgroup_item; +} t_cmdlist_item; typedef s_cmdlist { diff --git a/src/parser/command_list/command_list.c b/src/parser/command_list/command_list.c index a18a80f..7f93895 100644 --- a/src/parser/command_list/command_list.c +++ b/src/parser/command_list/command_list.c @@ -6,15 +6,16 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/24 17:49:46 by khais #+# #+# */ -/* Updated: 2025/03/04 15:23:00 by khais ### ########.fr */ +/* Updated: 2025/03/18 14:43:39 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include "command_list.h" +#include "command_list_item.h" #include "command_list_builder.h" +#include "command_list_item_type.h" #include "operator.h" #include "libft.h" -#include "../../ft_errno.h" #include #include @@ -45,9 +46,11 @@ static void cmdlist_builder_delimit( t_cmdlist_builder *builder, t_wordlist **words) { - builder->cmdlist->pipelines[builder->idx] + builder->cmdlist->cmds[builder->idx] = cmdlist_item_create(); + builder->cmdlist->cmds[builder->idx]->inner.pipeline = pipeline_from_wordlist(builder->current_wordlist); - if (builder->cmdlist->pipelines[builder->idx] == NULL) + builder->cmdlist->cmds[builder->idx]->type = TYPE_PIPELINE; + if (builder->cmdlist->cmds[builder->idx]->inner.pipeline == NULL) { cmdlist_builder_error(builder); wordlist_destroy(*words); @@ -104,12 +107,12 @@ void cmdlist_destroy(t_cmdlist *cmd) if (cmd == NULL) return ; i = 0; - while (i < cmd->num_pipelines) + while (i < cmd->num_cmds) { - pipeline_destroy(cmd->pipelines[i]); + cmdlist_item_destroy(cmd->cmds[i]); i++; } - free(cmd->pipelines); + free(cmd->cmds); free(cmd->operators); free(cmd); } diff --git a/src/parser/command_list/command_list.h b/src/parser/command_list/command_list.h index 1198ea1..f64bc90 100644 --- a/src/parser/command_list/command_list.h +++ b/src/parser/command_list/command_list.h @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/24 17:45:01 by khais #+# #+# */ -/* Updated: 2025/03/09 14:22:19 by khais ### ########.fr */ +/* Updated: 2025/03/18 12:59:56 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,6 +16,7 @@ # include "../wordlist/wordlist.h" # include "../pipeline/pipeline.h" # include "operator.h" +# include "../../buffer/buffer.h" /* ** cf. 3.2.4 Lists of Commands @@ -62,15 +63,15 @@ typedef struct s_cmdlist { /* - ** Array of pipelines contained in this command list. + ** Array of pointers to commands in this command list ** ** These should be executed left to right. */ - t_pipeline **pipelines; + struct s_cmdlist_item **cmds; /* - ** Number of pipelines in this command list. + ** Number of commands in this command list. */ - int num_pipelines; + int num_cmds; /* ** Operators that separate the pipelines. ** @@ -85,5 +86,6 @@ typedef struct s_cmdlist t_cmdlist *cmdlist_from_wordlist(const t_wordlist *wordlist); void cmdlist_destroy(t_cmdlist *cmd); +void cmdlist_debug(t_cmdlist *cmd, t_buffer **indent, bool is_last); #endif // COMMAND_LIST_H diff --git a/src/parser/command_list/command_list_builder.c b/src/parser/command_list/command_list_builder.c index 03048c5..2115cad 100644 --- a/src/parser/command_list/command_list_builder.c +++ b/src/parser/command_list/command_list_builder.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/26 13:51:18 by khais #+# #+# */ -/* Updated: 2025/03/09 14:24:05 by khais ### ########.fr */ +/* Updated: 2025/03/18 13:31:57 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -53,15 +53,15 @@ static t_cmdlist *allocate_command_list(t_wordlist *words) output = ft_calloc(1, sizeof(t_cmdlist)); if (output == NULL) return (NULL); - output->num_pipelines = command_list_count_pipelines(words); - output->pipelines - = ft_calloc(output->num_pipelines, sizeof(t_pipeline *)); - if (output->pipelines == NULL) + output->num_cmds = command_list_count_pipelines(words); + output->cmds + = ft_calloc(output->num_cmds, sizeof(struct s_cmdlist_item **)); + if (output->cmds == NULL) return (free(output), NULL); output->operators - = ft_calloc(output->num_pipelines, sizeof(t_operator)); + = ft_calloc(output->num_cmds, sizeof(t_operator)); if (output->operators == NULL) - return (free(output->pipelines), free(output), NULL); + return (free(output->cmds), free(output), NULL); return (output); } @@ -100,5 +100,5 @@ void cmdlist_builder_next_word( */ bool cmdlist_builder_at_last_pipeline(t_cmdlist_builder *builder) { - return (builder->idx == builder->cmdlist->num_pipelines - 1); + return (builder->idx == builder->cmdlist->num_cmds - 1); } diff --git a/src/parser/command_list/command_list_builder.h b/src/parser/command_list/command_list_builder.h index 7c6a3ac..ace809a 100644 --- a/src/parser/command_list/command_list_builder.h +++ b/src/parser/command_list/command_list_builder.h @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/26 13:50:25 by khais #+# #+# */ -/* Updated: 2025/03/04 15:23:55 by khais ### ########.fr */ +/* Updated: 2025/03/18 12:59:57 by khais ### ########.fr */ /* */ /* ************************************************************************** */ diff --git a/src/parser/command_list/command_list_item.c b/src/parser/command_list/command_list_item.c new file mode 100644 index 0000000..dbbfa1a --- /dev/null +++ b/src/parser/command_list/command_list_item.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* command_list_item.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: khais +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/03/18 13:02:02 by khais #+# #+# */ +/* Updated: 2025/03/18 13:35:25 by khais ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "command_list_item.h" +#include "libft.h" + +void cmdlist_item_destroy(t_cmdlist_item *cmd) +{ + if (cmd == NULL) + return ; + if (cmd->type == TYPE_CMDGROUP) + cmdgroup_destroy(cmd->inner.cmdgroup); + if (cmd->type == TYPE_PIPELINE) + pipeline_destroy(cmd->inner.pipeline); + free(cmd); +} + +t_cmdlist_item *cmdlist_item_create(void) +{ + t_cmdlist_item *item; + + item = ft_calloc(1, sizeof(t_cmdlist_item)); + if (item == NULL) + return (NULL); + item->type = TYPE_INVALID; + return (item); +} diff --git a/src/parser/cmdgroup/cmdgroup_item.h b/src/parser/command_list/command_list_item.h similarity index 56% rename from src/parser/cmdgroup/cmdgroup_item.h rename to src/parser/command_list/command_list_item.h index 619f495..0fc2abc 100644 --- a/src/parser/cmdgroup/cmdgroup_item.h +++ b/src/parser/command_list/command_list_item.h @@ -1,30 +1,32 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* cmdgroup_item.h :+: :+: :+: */ +/* command_list_item.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/11 15:43:15 by khais #+# #+# */ -/* Updated: 2025/03/11 18:10:24 by khais ### ########.fr */ +/* Created: 2025/03/18 12:54:31 by khais #+# #+# */ +/* Updated: 2025/03/18 13:34:14 by khais ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef CMDGROUP_ITEM_H -# define CMDGROUP_ITEM_H +#ifndef COMMAND_LIST_ITEM_H +# define COMMAND_LIST_ITEM_H -# include "cmdgroup_item_type.h" -# include "../command_list/command_list.h" -# include "cmdgroup.h" +# include "../cmdgroup/cmdgroup.h" +# include "command_list_item_type.h" -typedef struct s_cmdgroup_item +typedef struct s_cmdlist_item { - enum e_cmdgroup_item_type type; - union u_cmdgroup_item_inner + enum e_cmdlist_item_type type; + union u_cmdlist_item_inner { t_cmdgroup *cmdgroup; - struct s_cmdlist *cmdlist; + struct s_pipeline *pipeline; } inner; -} t_cmdgroup_item; +} t_cmdlist_item; -#endif // CMDGROUP_ITEM_H +void cmdlist_item_destroy(t_cmdlist_item *cmd); +t_cmdlist_item *cmdlist_item_create(void); + +#endif // COMMAND_LIST_ITEM_H diff --git a/src/parser/cmdgroup/cmdgroup_item_type.h b/src/parser/command_list/command_list_item_type.h similarity index 63% rename from src/parser/cmdgroup/cmdgroup_item_type.h rename to src/parser/command_list/command_list_item_type.h index 4f59f4d..7e9e029 100644 --- a/src/parser/cmdgroup/cmdgroup_item_type.h +++ b/src/parser/command_list/command_list_item_type.h @@ -1,23 +1,23 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* cmdgroup_item_type.h :+: :+: :+: */ +/* command_list_item_type.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2025/03/11 15:45:33 by khais #+# #+# */ -/* Updated: 2025/03/11 15:46:25 by khais ### ########.fr */ +/* Created: 2025/03/18 12:56:30 by khais #+# #+# */ +/* Updated: 2025/03/18 12:58:38 by khais ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef CMDGROUP_ITEM_TYPE_H -# define CMDGROUP_ITEM_TYPE_H +#ifndef COMMAND_LIST_ITEM_TYPE_H +# define COMMAND_LIST_ITEM_TYPE_H -typedef enum e_cmdgroup_item_type +typedef enum e_cmdlist_item_type { - TYPE_INVALID = 0, - TYPE_GROUP, - TYPE_LIST, -} t_cmdgroup_item_type; + TYPE_INVALID, + TYPE_CMDGROUP, + TYPE_PIPELINE, +} t_cmdlist_item_type; -#endif // CMDGROUP_ITEM_TYPE_H +#endif // COMMAND_LIST_ITEM_TYPE_H diff --git a/tests/Makefile b/tests/Makefile index aab4b01..86bbe47 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -2,11 +2,11 @@ # file are prefixed with test_ rawtests = \ expansion \ + test_cmdlist_use_after_free \ test_here_doc \ test_wordlist_idx \ test_redirection_parsing \ test_quote_removal \ - test_cmdlist_use_after_free \ test_metacharacters \ test_parse_command_lists \ test_parse_pipelines \ diff --git a/tests/test_cmdlist_use_after_free.c b/tests/test_cmdlist_use_after_free.c index b284468..85b6e31 100644 --- a/tests/test_cmdlist_use_after_free.c +++ b/tests/test_cmdlist_use_after_free.c @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* cmdlist_use_after_free.c :+: :+: :+: */ +/* test_cmdlist_use_after_free.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/03/03 11:40:37 by khais #+# #+# */ -/* Updated: 2025/03/04 13:27:54 by khais ### ########.fr */ +/* Updated: 2025/03/18 14:23:19 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,8 +17,11 @@ int main(void) { - t_wordlist *words = minishell_wordsplit("|"); - t_cmdlist *cmd = cmdlist_from_wordlist(words); + t_wordlist *words; + t_cmdlist *cmd; + cmd = NULL; + words = minishell_wordsplit("|"); + cmd = cmdlist_from_wordlist(words); wordlist_destroy(words); assert(cmd == NULL); return (0); diff --git a/tests/test_parse_command_lists.c b/tests/test_parse_command_lists.c index 0465128..236c3b1 100644 --- a/tests/test_parse_command_lists.c +++ b/tests/test_parse_command_lists.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/24 17:40:48 by khais #+# #+# */ -/* Updated: 2025/03/11 16:30:05 by khais ### ########.fr */ +/* Updated: 2025/03/18 13:09:51 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -33,7 +33,7 @@ static void test_parse_command_list_single_pipeline(void) assert(cmd != NULL); assert_pipelineequal("echo this | cat -e", cmd, 0); assert(cmd->operators[0] == OP_END); - assert(cmd->num_pipelines == 1); + assert(cmd->num_cmds == 1); cmdlist_destroy(cmd); } @@ -45,7 +45,7 @@ static void test_parse_command_list_simple_and(void) assert_pipelineequal("echo this | cat -e", cmd, 0); assert(cmd->operators[0] == OP_AND); assert_pipelineequal("echo works | wc -c", cmd, 1); - assert(cmd->num_pipelines == 2); + assert(cmd->num_cmds == 2); cmdlist_destroy(cmd); } @@ -57,7 +57,7 @@ static void test_parse_command_list_simple_or(void) assert_pipelineequal("echo this | cat -e", cmd, 0); assert(cmd->operators[0] == OP_OR); assert_pipelineequal("echo works | wc -c", cmd, 1); - assert(cmd->num_pipelines == 2); + assert(cmd->num_cmds == 2); cmdlist_destroy(cmd); } @@ -71,7 +71,7 @@ static void test_parse_command_list_triple_or(void) assert_pipelineequal("echo works | wc -c", cmd, 1); assert(cmd->operators[1] == OP_OR); assert_pipelineequal("echo as well | cut -d' ' -f1", cmd, 2); - assert(cmd->num_pipelines == 3); + assert(cmd->num_cmds == 3); cmdlist_destroy(cmd); } @@ -86,7 +86,7 @@ static void test_parse_command_list_triple_both_operators(void) assert(cmd->operators[1] == OP_AND); assert_pipelineequal("echo as well | cut -d' ' -f1", cmd, 2); assert(cmd->operators[2] == OP_END); - assert(cmd->num_pipelines == 3); + assert(cmd->num_cmds == 3); cmdlist_destroy(cmd); } @@ -121,7 +121,7 @@ static void test_parse_command_list_simple_command(void) assert(cmd != NULL); assert_pipelineequal("echo this", cmd, 0); assert(cmd->operators[0] == OP_END); - assert(cmd->num_pipelines == 1); + assert(cmd->num_cmds == 1); cmdlist_destroy(cmd); } diff --git a/tests/testutil.c b/tests/testutil.c index 779e114..a6a84e1 100644 --- a/tests/testutil.c +++ b/tests/testutil.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 15:21:09 by khais #+# #+# */ -/* Updated: 2025/03/18 11:50:23 by khais ### ########.fr */ +/* Updated: 2025/03/18 13:09:16 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,7 +19,7 @@ #include "parse_pipeline.h" #include "../src/parser/wordlist/wordlist.h" #include "../src/parser/wordsplit/wordsplit.h" -#include "../src/parser/cmdgroup/cmdgroup_item.h" +#include "../src/parser/command_list/command_list_item.h" void assert_strequal(char *str1, char *str2) { @@ -84,9 +84,9 @@ void assert_pipelineequal_raw(t_pipeline *expected, t_pipeline *got) void assert_pipelineequal(char *expected, t_cmdlist *cmd, int idx) { - ft_printf("Expected command list %p to have at least %d pipelines, and got %d\n", cmd, idx + 1, cmd->num_pipelines); - assert(cmd->num_pipelines >= idx + 1); - t_pipeline *got = cmd->pipelines[idx]; + ft_printf("Expected command list %p to have at least %d pipelines, and got %d\n", cmd, idx + 1, cmd->num_cmds); + assert(cmd->num_cmds >= idx + 1); + t_pipeline *got = cmd->cmds[idx]->inner.pipeline; ft_dprintf(STDERR_FILENO, "Expected pipeline %p to equal [%s]\n", got, expected); t_pipeline *expected_pipeline = parse_pipeline(expected); assert_pipelineequal_raw(expected_pipeline, got); @@ -136,7 +136,7 @@ void assert_cmdgroup_itemlistequal(char *expected_str, t_cmdgroup *got_cmd, int } ft_dprintf(STDERR_FILENO, "checking if the list matches...\n"); int i = 0; - while (i < expected->num_pipelines) + while (i < expected->num_cmds) { i++; }