minishell
ft_strtol.c
Go to the documentation of this file.
1 /* ************************************************************************** */
2 /* */
3 /* ::: :::::::: */
4 /* ft_strtol.c :+: :+: :+: */
5 /* +:+ +:+ +:+ */
6 /* By: kfujita <kfujita@student.42tokyo.jp> +#+ +:+ +#+ */
7 /* +#+#+#+#+#+ +#+ */
8 /* Created: 2022/04/23 22:28:22 by kfujita #+# #+# */
9 /* Updated: 2022/04/25 23:30:03 by kfujita ### ########.fr */
10 /* */
11 /* ************************************************************************** */
12 
13 #include <limits.h>
14 #include "ft_string.h"
15 
16 static int get_36based_value(char c)
17 {
18  if ('0' <= c && c <= '9')
19  return (c - '0');
20  else if ('a' <= c && c <= 'z')
21  return (c - 'a' + 10);
22  else if ('A' <= c && c <= 'Z')
23  return (c - 'A' + 10);
24  else
25  return (-1);
26 }
27 
28 static int set_value(char c, long *p_value, int sign, int base)
29 {
30  int num_value;
31  long value_tmp;
32 
33  num_value = get_36based_value(c);
34  if (num_value < 0 || base <= num_value)
35  return (0 == 1);
36  num_value *= sign;
37  value_tmp = (*p_value) * base;
38  if (sign > 0 && (((LONG_MAX / base) < *p_value)
39  || ((LONG_MAX - value_tmp) < num_value)))
40  *p_value = LONG_MAX;
41  else if (sign < 0 && (((LONG_MIN / base) > *p_value)
42  || ((LONG_MIN - value_tmp) > num_value)))
43  *p_value = LONG_MIN;
44  else
45  {
46  *p_value = value_tmp + num_value;
47  return (0 == 0);
48  }
49  return (0 == 1);
50 }
51 
52 static int get_base(const char **p_str, const int base)
53 {
54  if (base != 0)
55  return (base);
56  if ((*p_str)[0] == '0')
57  {
58  if ((*p_str)[1] == 'x')
59  {
60  (*p_str)++;
61  return (16);
62  }
63  else
64  return (8);
65  }
66  return (10);
67 }
68 
69 long ft_strtol(const char *str, char **endptr, int base)
70 {
71  long sign;
72  long value;
73 
74  sign = 1;
75  value = 0;
76  if (endptr != NULL)
77  *endptr = (char *)str;
78  if (!((2 <= base && base <= 36) || base == 0))
79  return (0);
80  while (((9 <= *str && *str <= 13) || *str == ' ') && *str != '\0')
81  str++;
82  if (*str == '-')
83  sign = -1;
84  else if (*str != '+' && !(('a' <= *str && *str <= 'z')
85  || ('A' <= *str && *str <= 'Z') || ('0' <= *str && *str <= '9')))
86  return (0);
87  if (*str == '+' || *str == '-')
88  str++;
89  base = get_base(&str, base);
90  while (set_value(*str, &value, sign, base))
91  str++;
92  if (endptr != NULL)
93  *endptr = (char *)str;
94  return (value);
95 }
static int get_base(const char **p_str, const int base)
Definition: ft_strtol.c:52
long ft_strtol(const char *str, char **endptr, int base)
Definition: ft_strtol.c:69
static int set_value(char c, long *p_value, int sign, int base)
Definition: ft_strtol.c:28
static int get_36based_value(char c)
Definition: ft_strtol.c:16