-
Notifications
You must be signed in to change notification settings - Fork 0
/
ft_atoi.c
104 lines (92 loc) · 2.86 KB
/
ft_atoi.c
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
92
93
94
95
96
97
98
99
100
101
102
103
104
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* ft_atoi.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: lgasc <lgasc@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2023/02/04 16:28:25 by lgasc #+# #+# */
/* Updated: 2024/03/11 20:29:43 by lgasc ### ########.fr */
/* */
/* ************************************************************************** */
#include "libft.h"
//#include "ft_atoi.h"
//\// Indeed, `clang` seems to support no attribute...
//# ifndef __clang__
//# ifdef TEST
//
//const struct __attribute__ ((designated_init)) s_skip
//{
// const size_t index;
// const signed char sign;
//};
//# define S_SKIP
//# endif
//# endif
//# ifndef S_SKIP
//struct s_skip
//{
// const size_t index;
// const signed char sign;
//};
//#endif
static struct s_skip ft_skip_prefix(const char *const string)
__attribute__ ((warn_unused_result))
__attribute__ ((nonnull));
///@remark This function aims to replicate the `libc` function `atoi`.
int ft_atoi(const char *string)
{
const struct s_skip skip = ft_skip_prefix(string);
size_t i;
signed char sign;
int number;
i = skip.index;
sign = skip.sign;
number = 0;
while (1)
if (! ft_isdigit(string[i]))
return (number);
else
number = number * 10 + sign * (string[i++] - '0');
}
//#define S sign
//#define I integer
//#define C string
t_atoi_result ft_try_atoi(const char string[const])
{
const struct s_skip skip = ft_skip_prefix(string);
size_t i;
signed char sign;
int integer;
if (string == NULL)
return ((t_atoi_result){.code = Atoi_NullString});
i = skip.index;
sign = skip.sign;
if (! ft_isdigit(string[i]))
return ((t_atoi_result){.code = Atoi_NonNumeric});
integer = 0;
while (1)
{
integer = integer * 10 + sign * (string[i++] - '0');
if (! ft_isdigit(string[i]))
return ((t_atoi_result){.code = Atoi_Ok, .ok = integer});
if ((sign > 0 && integer > (INT_MAX - string[i] + '0') / 10)
|| (sign < 0 && integer < (INT_MIN + string[i] - '0') / 10))
return ((t_atoi_result){.code = Atoi_BeyondLimits});
}
}
// Statics
static struct s_skip ft_skip_prefix(const char *const string)
{
size_t index;
signed char sign;
index = 0;
while (ft_isspace(string[index]))
++index;
sign = 1;
if (string[index] == '-')
sign = -1;
if (string[index] == '+' || string[index] == '-')
++index;
return ((struct s_skip){.index = index, .sign = sign});
}