-
Notifications
You must be signed in to change notification settings - Fork 0
/
precision_width_diuxp.c
153 lines (139 loc) · 5.45 KB
/
precision_width_diuxp.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* ************************************************************************** */
/* */
/* :::::::: */
/* precision_width_diuxp.c :+: :+: */
/* +:+ */
/* By: kawish <[email protected]> +#+ */
/* +#+ */
/* Created: 2021/02/23 12:56:31 by kawish #+# #+# */
/* Updated: 2021/03/06 13:13:32 by kawish ######## odam.nl */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
/* Helps the precision_diuxp() and width_diuxp()
functions to handle negative values.
Works by setting the first character of data->b_dup
to '-' sign. And setting data->a_dup one character
forward to ignore the minus sign before continuing
with the calling function.
t_data *data -- pointer to struct that contains information on
the variadic argument to be formatted and printed
*/
static void diuxp_nega_helper(t_data *data)
{
*data->b_dup++ = '-';
data->a_dup++;
}
/* Handles the precision for %d, %i, %u, %x, and %p specifiers.
1. Check if the precision is smaller than the number of
characters in the converted(!) value.
2. Malloc data->b with enough memory to hold precision,
data->a_len and terminating null character. Also fill data->b
width '0'.
3. Use data-b_dup to move around the data->b string without losing
original position.
4. If the first character of the converted(!) value is '-':
I. Set data->b_dup's first character to '-'.
and Increment data->b_dup by one.
II. Increment data->a_dup by one.
This will turn a string representation of a negative number
into a string representation of a positive number. And set
the '-' sign in the correct place in the converted string.
After which the regular flow can be followed.
Copy the converted value data->a_dup to the
(data->b_dup + (fields->precision - data->a_digits))th position in the
string of data->b_dup.
5. Set a null terminating character at the fields->precision'th index
of data->b_dup.
6. Set data->a to data->b.
7. Set data->a_dup to the new data->a.
8. Updates data->a_len because data->a points to a new string.
9. Handle one off edge case.
t_fields *fields -- pointer to struct that contains information
on fields
t_data *data -- pointer to struct that contains information on
the variadic argument to be formatted and printed
*/
void precision_diuxp(t_fields *fields, t_data *data)
{
if (fields->precision >= 0 && data->a_digits < fields->precision)
{
data->b = zalloc(fields->precision + data->a_len + 1,
sizeof(*(data->b)), '0');
if (!data->b)
{
fields->count = -1;
return ;
}
data->b_dup = data->b;
if (*data->a == '-')
diuxp_nega_helper(data);
ft_memcpy(data->b_dup + (fields->precision - data->a_digits),
data->a_dup, ft_strlen(data->a_dup));
data->b_dup[fields->precision] = '\0';
free(data->a);
data->a = data->b;
data->a_dup = data->a;
}
else if (fields->precision == 0 && (*data->a == '0' && data->a[1] == '\0'))
data->a[0] = '\0';
data->a_len = ft_strlen(data->a);
}
/* Handles the width for %d, %i, %u, %x, and %p specifiers.
1. Check if the converted(!) value has fewer characters than the
field width.
2. Malloc data->b with enough memory to hold width, data->a_len and
terminating null character. Also fill data->b with
fields->padding_char.
3. Use data-b_dup to move around the data->b string without losing
original position.
4. If data->minus is true, copies the converted value data->a to
the beginning of data->b_dup.
If data->minus is false, check for case where the converted(!)
value is negative and the padding_char == '0'. If so:
I. Set data->b_dup's first character to '-'.
and Increment data->b_dup by one.
II. Increment data->a_dup by one.
This will turn a string representation of a negative number
into a string representation of a positive number. And set
the '-' sign in the correct place in the converted string.
After which the regular flow can be followed.
Copy the converted value data->a_dup to the
(data->b_dup + (fields->width - data->a_len))th position in the
string of data->b_dup.
5. Null terminate data->b on index fields->width.
6. Free data->a to prevent unfreed malloced memory.
7. Set data->a to data->b.
8. Updates data->a_len because data->a points to a new string.
t_fields *fields -- pointer to struct that contains information
on fields
t_data *data -- pointer to struct that contains information on
the variadic argument to be formatted and printed
*/
void width_diuxp(t_data *data, t_fields *fields)
{
if ((int)data->a_len < fields->width)
{
data->b = zalloc(fields->width + data->a_len + 1,
sizeof(*(data->b)), fields->padding_char);
if (!data->b)
{
fields->count = -1;
return ;
}
data->b_dup = data->b;
if (fields->is_minus)
ft_memcpy(data->b_dup, data->a, data->a_len);
else
{
if (*data->a == '-' && fields->padding_char == '0')
diuxp_nega_helper(data);
ft_memcpy(data->b_dup + (fields->width - data->a_len),
data->a_dup, ft_strlen(data->a_dup));
}
data->b[fields->width] = '\0';
free(data->a);
data->a = data->b;
data->a_len = ft_strlen(data->a);
}
}