From 4171a3d07b65f9d07991d4a3e086ddfa9fe91e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kha=C3=AFs=20COLIN?= Date: Fri, 14 Feb 2025 15:44:10 +0100 Subject: [PATCH] wordsplit: handle multiple words --- src/parser/wordlist/wordlist.c | 43 ++++++++++++++++++++++++++++---- src/parser/wordlist/wordlist.h | 3 ++- src/parser/wordsplit/wordsplit.c | 31 +++++++++++++++++------ tests/word_splitting.c | 8 +++--- 4 files changed, 68 insertions(+), 17 deletions(-) diff --git a/src/parser/wordlist/wordlist.c b/src/parser/wordlist/wordlist.c index 1aebfea..5eb1a5e 100644 --- a/src/parser/wordlist/wordlist.c +++ b/src/parser/wordlist/wordlist.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 17:07:01 by khais #+# #+# */ -/* Updated: 2025/02/14 13:56:45 by khais ### ########.fr */ +/* Updated: 2025/02/14 16:47:04 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,10 +37,15 @@ t_wordlist *wordlist_create(t_worddesc *word) */ void wordlist_destroy(t_wordlist *wordlist) { - if (wordlist == NULL) - return ; - worddesc_destroy(wordlist->word); - free(wordlist); + t_wordlist *prev; + + while (wordlist != NULL) + { + worddesc_destroy(wordlist->word); + prev = wordlist; + wordlist = wordlist->next; + free(prev); + } } /* @@ -53,8 +58,36 @@ t_worddesc *wordlist_get(t_wordlist *wordlist, int idx) if (wordlist == NULL || idx < 0) return (NULL); while (idx > 0 && wordlist != NULL) + { wordlist = wordlist->next; + idx--; + } if (wordlist == NULL) return (NULL); return (wordlist->word); } + +/* +** push the given worddesc to the end of the given wordlist. +** +** if wordlist is null, create a new wordlist. +** +** returns a pointer to the first element in the wordlist. +** +** if malloc failure is encountered, all memory for this wordlist is freed, and +** null is returned. +*/ +t_wordlist *wordlist_push(t_wordlist *wordlist, t_worddesc *worddesc) +{ + t_wordlist *start; + + if (wordlist == NULL) + return (wordlist_create(worddesc)); + start = wordlist; + while (wordlist->next != NULL) + wordlist = wordlist->next; + wordlist->next = wordlist_create(worddesc); + if (wordlist->next == NULL) + return (wordlist_destroy(start), NULL); + return (start); +} diff --git a/src/parser/wordlist/wordlist.h b/src/parser/wordlist/wordlist.h index fbf8b46..b832d01 100644 --- a/src/parser/wordlist/wordlist.h +++ b/src/parser/wordlist/wordlist.h @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 15:46:02 by khais #+# #+# */ -/* Updated: 2025/02/14 13:29:05 by khais ### ########.fr */ +/* Updated: 2025/02/14 15:48:36 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -37,5 +37,6 @@ typedef struct s_wordlist t_wordlist *wordlist_create(t_worddesc *word); void wordlist_destroy(t_wordlist *wordlist); t_worddesc *wordlist_get(t_wordlist *wordlist, int idx); +t_wordlist *wordlist_push(t_wordlist *wordlist, t_worddesc *worddesc); #endif diff --git a/src/parser/wordsplit/wordsplit.c b/src/parser/wordsplit/wordsplit.c index 5db7d6d..ce297b7 100644 --- a/src/parser/wordsplit/wordsplit.c +++ b/src/parser/wordsplit/wordsplit.c @@ -6,7 +6,7 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 17:02:32 by khais #+# #+# */ -/* Updated: 2025/02/14 15:22:57 by khais ### ########.fr */ +/* Updated: 2025/02/14 16:46:27 by khais ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,12 +26,27 @@ */ t_wordlist *minishell_wordsplit(char *original) { - size_t start; - size_t length; - char *outstr; + size_t start; + size_t idx; + size_t length; + char *word; + t_wordlist *wordlist; - start = ft_strnfchridx(original, is_blank); - length = ft_strfchridx(original + start, is_blank); - outstr = ft_substr(original, start, length); - return (wordlist_create(worddesc_create(outstr))); + start = 0; + idx = 0; + wordlist = NULL; + length = 1; + while (length != 0) + { + start = ft_strnfchridx(original + idx, is_blank); + length = ft_strfchridx(original + idx + start, is_blank); + if (length == 0) + break ; + word = ft_substr(original + idx, start, length); + wordlist = wordlist_push(wordlist, worddesc_create(word)); + if (wordlist == NULL) + return (NULL); + idx += start + length; + } + return (wordlist); } diff --git a/tests/word_splitting.c b/tests/word_splitting.c index 29ca564..b20aed4 100644 --- a/tests/word_splitting.c +++ b/tests/word_splitting.c @@ -6,12 +6,13 @@ /* By: khais +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/02/13 15:17:56 by khais #+# #+# */ -/* Updated: 2025/02/14 15:06:50 by khais ### ########.fr */ +/* Updated: 2025/02/14 16:16:14 by khais ### ########.fr */ /* */ /* ************************************************************************** */ #include #include "testutil.h" +#include "libft.h" #include "../src/parser/wordsplit/wordsplit.h" #include @@ -38,11 +39,11 @@ void test_wordsplit_singleword_with_blanks(void) wordlist_destroy(words); } -void test_wordsplit_basic(void) +void test_wordsplit_multiword(void) { t_wordlist *words; - words = minishell_wordsplit("echo The file is named $MYFILE"); + words = minishell_wordsplit("\t echo\tThe file is named $MYFILE \t"); assert_strequal("echo", wordlist_get(words, 0)->word); assert_strequal("The", wordlist_get(words, 1)->word); assert_strequal("file", wordlist_get(words, 2)->word); @@ -56,5 +57,6 @@ void test_wordsplit_basic(void) int main(void) { test_wordsplit_singleword(); test_wordsplit_singleword_with_blanks(); + test_wordsplit_multiword(); return (0); }