/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* ft_split_quotes.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lperrey +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2021/11/13 07:08:40 by lperrey #+# #+# */ /* Updated: 2021/11/13 22:35:34 by lperrey ### ########.fr */ /* */ /* ************************************************************************** */ #include "minishell.h" enum e_in_quote_state { NOT_IN = 0, IN_QUOTES = '\'', IN_DQUOTES = '\"' }; static size_t count_word(char const *s, char c); static char **alloc_words(char const *s, char c, char **str_arr, size_t words_count); static void fill_arr(char const *s, char c, char **str_arr); static int quote_state_change(int *quote_state, const char *s); char **ft_split_quotes(char const *s, char c) { char **str_arr; size_t words_count; if (s == NULL) return (NULL); words_count = count_word(s, c); str_arr = ft_calloc(words_count + 1, sizeof(char *)); if (!str_arr) return (NULL); if (!(alloc_words(s, c, str_arr, words_count))) { ft_free_2d_arr(str_arr); return (NULL); } fill_arr(s, c, str_arr); return (str_arr); } static size_t count_word(char const *s, char c) { unsigned int i; size_t count; int quote_state; i = 0; count = 0; quote_state = 0; while (s[i]) { while (s[i] == c) i++; if (s[i]) count++; while (s[i] && (s[i] != c || quote_state)) { while (quote_state_change("e_state, &s[i])) i++; if (s[i] && (s[i] != c || quote_state)) i++; } } return (count); } static char **alloc_words(char const *s, char c, char **str_arr, size_t words_count) { unsigned int i; size_t len; unsigned int arr_i; int quote_state; i = 0; arr_i = 0; quote_state = 0; while (arr_i < words_count) { len = 0; while (s[i] == c) i++; while (s[i + len] && (quote_state_change("e_state, &s[i + len]) || (s[i + len] != c || quote_state))) len++; i = i + len; str_arr[arr_i] = ft_calloc(len + 1, 1); if (!str_arr[arr_i]) return (NULL); arr_i++; } return (str_arr); } // Plus clair, plus de 25 lignes :( /* static char **alloc_words(char const *s, char c, char **str_arr, size_t words_count) { unsigned int i; size_t len; unsigned int arr_i; int quote_state; i = 0; arr_i = 0; quote_state = 0; while (arr_i < words_count) { len = 0; while (s[i] == c) i++; while (s[i + len] && (s[i + len] != c || quote_state)) { while (quote_state_change("e_state, &s[i + len])) len++; if (s[i + len] != c || quote_state) len++; } i = i + len; str_arr[arr_i] = ft_calloc(len + 1, 1); if (!str_arr[arr_i]) return (NULL); arr_i++; } return (str_arr); } */ static void fill_arr(char const *s, char c, char **str_arr) { unsigned int i; unsigned int arr_i; unsigned int char_i; int quote_state; i = 0; arr_i = 0; quote_state = 0; while (str_arr[arr_i]) { while (s[i] == c) i++; char_i = 0; while (s[i] && (s[i] != c || quote_state)) { while (quote_state_change("e_state, &s[i])) str_arr[arr_i][char_i++] = s[i++]; if (s[i] && (s[i] != c || quote_state)) str_arr[arr_i][char_i++] = s[i++]; } str_arr[arr_i][char_i] = '\0'; //superflu si ft_calloc arr_i++; } } static int quote_state_change(int *quote_state, const char *s) { if (s[0] == '\'' && *quote_state != IN_DQUOTES) { if (*quote_state == IN_QUOTES) *quote_state = 0; else if (ft_strchr(&s[1], '\'')) // if closed quotes *quote_state = IN_QUOTES; else return (0); return (1); } else if (s[0] == '\"' && *quote_state != IN_QUOTES) { if (*quote_state == IN_DQUOTES) *quote_state = 0; else if (ft_strchr(&s[1], '\"')) // if closed quotes *quote_state = IN_DQUOTES; else return (0); return (1); } return (0); }