187 lines
4.2 KiB
C
187 lines
4.2 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* ft_split_quotes.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: lperrey <lperrey@student.42.fr> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* 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);
|
|
}
|