-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcvt_unbr.c
115 lines (105 loc) · 3.27 KB
/
cvt_unbr.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
105
106
107
108
109
110
111
112
113
114
115
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* cvt_unbr.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: rvan-der <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2016/10/24 17:48:46 by rvan-der #+# #+# */
/* Updated: 2016/11/10 17:29:59 by rvan-der ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
char *get_prefix(t_conv c, uintmax_t nbr)
{
if (((c.type == O || c.type == o) && c.altern) || (!nbr && c.prec != 0))
return ("0");
if ((c.altern && nbr && (c.type == x || c.type == X)) || c.type == p)
return (c.type == X ? "0X" : "0x");
return (NULL);
}
char *ft_itoabase_pf(t_conv c, uintmax_t n, int range,\
char *base)
{
int i;
char *nbr;
char *prefix;
int base_len;
if ((nbr = (char*)malloc(sizeof(char) * (range + 1))) == NULL)
return (NULL);
if ((prefix = get_prefix(c, n)) != NULL)
{
i = -1;
while (prefix[++i] != '\0')
nbr[i] = prefix[i];
}
base_len = ft_strlen(base);
i = range - 1;
while (n != 0)
{
nbr[i--] = base[n % base_len];
n = n / base_len;
}
nbr[range] = '\0';
return (nbr);
}
int find_range(t_conv c, uintmax_t n, int base_len)
{
int range;
range = 0;
if (c.type == p || (c.altern && (c.type == x || c.type == X) && n))
range = 2;
else if ((!n && c.prec != 0) ||\
(c.altern && (c.type == o || c.type == O)))
range = 1;
while (n != 0)
{
range++;
n = n / base_len;
}
return (range);
}
uintmax_t get_nbr(t_mod m, t_type t, va_list args)
{
t_val nbr;
if ((t == u || t == o || t == x || t == X) && !m)
return ((uintmax_t)(nbr.uin = va_arg(args, unsigned)));
if (t != p && m == h)
{
return ((uintmax_t)(unsigned short)(nbr.hun =\
va_arg(args, unsigned int)));
}
if (((t == u || t == o || t == x || t == X) && m == l) ||\
((t == U || t == O) && !m) || (t != p && m == z))
return ((uintmax_t)(nbr.lun = va_arg(args, unsigned long)));
if (m == ll || t == p)
return ((uintmax_t)(nbr.llu = va_arg(args, unsigned long long)));
if (t != p && m == hh)
{
return ((uintmax_t)(unsigned char)(nbr.uch =\
va_arg(args, unsigned int)));
}
if (t != p && m == j)
return ((nbr.unm = va_arg(args, uintmax_t)));
return (0);
}
char *cvt_unbr(t_conv c, va_list args)
{
uintmax_t nbr;
char *res;
int range;
char *base;
int pfx;
base = get_base(c.type);
nbr = get_nbr(c.mod, c.type, args);
if (c.type == p && !nbr)
return (c.prec > -1 ? ft_chgprec(ft_strdup("0x0"), 3, c.prec, 2) :\
ft_strdup("0x0"));
range = find_range(c, nbr, ft_strlen(base));
if ((res = ft_itoabase_pf(c, nbr, range, base)) == NULL)
return (NULL);
if (range - (pfx = get_pfxlen(res, c)) < c.prec)
if ((res = ft_chgprec(res, range, c.prec, pfx)) == NULL)
return (NULL);
return (res);
}