summaryrefslogtreecommitdiff
path: root/libft/ft_split.c
blob: bce2f72a6e15bec50307fcc9d2aead6b4154f11b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* ************************************************************************** */
/*                                                                            */
/*                                                        :::      ::::::::   */
/*   ft_split.c                                         :+:      :+:    :+:   */
/*                                                    +:+ +:+         +:+     */
/*   By: kdx    <kdx   @student.42angouleme.fr      +#+  +:+       +#+        */
/*                                                +#+#+#+#+#+   +#+           */
/*   Created: 2022/09/28 16:55:02 by kdx               #+#    #+#             */
/*   Updated: 2022/10/13 22:34:28 by kdx              ###   ########.fr       */
/*                                                                            */
/* ************************************************************************** */

#include "libft.h"
#include <stdbool.h>

static void	*free_array(char **a)
{
	size_t	i;

	if (a != NULL)
	{
		i = 0;
		while (a[i] != NULL)
		{
			free(a[i]);
			i += 1;
		}
		free(a);
	}
	return (NULL);
}

static size_t	skip_char(const char **s, char c, bool invert)
{
	size_t		i;
	const char	*p;

	i = 0;
	p = *s;
	while (((!invert && *p == c) || (invert && *p != c)) && *p != '\0')
	{
		p += 1;
		i += 1;
	}
	*s = p;
	return (i);
}

static size_t	count_elems(const char *s, char c)
{
	size_t	n_elem;

	n_elem = 0;
	skip_char(&s, c, false);
	while (*s != '\0')
	{
		skip_char(&s, c, true);
		skip_char(&s, c, false);
		n_elem += 1;
	}
	return (n_elem);
}

char	**ft_split(char const *s, char c)
{
	char		**array;
	size_t		n_elem;
	size_t		arr_i;
	const char	*rem_s;
	size_t		len;

	if (s == NULL)
		return (NULL);
	n_elem = count_elems(s, c);
	array = ft_calloc(n_elem + 1, sizeof(char *));
	if (array == NULL)
		return (array);
	skip_char(&s, c, false);
	arr_i = 0;
	while (arr_i < n_elem)
	{
		rem_s = s;
		len = skip_char(&s, c, true);
		array[arr_i] = ft_substr(rem_s, 0, len);
		if (array[arr_i] == NULL)
			return (free_array(array));
		arr_i += 1;
		skip_char(&s, c, false);
	}
	return (array);
}