Directory: | ./ |
---|---|
File: | s21_sscanf_handlers.c |
Date: | 2025-07-13 17:59:14 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 105 | 105 | 100.0% |
Branches: | 58 | 58 | 100.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | #include "s21_sscanf.h" | ||
2 | |||
3 | 14 | int handleCharScan(const char** str, const FormatSpecifierScan* fs, | |
4 | va_list args, int* countOfRead) { | ||
5 |
2/2✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
|
14 | if (fs->assignable) { |
6 | 7 | char* toAssign = va_arg(args, char*); | |
7 | 7 | *toAssign = **str; | |
8 | 7 | (*countOfRead)++; | |
9 | } | ||
10 | |||
11 | 14 | (*str)++; | |
12 | |||
13 | 14 | return 1; | |
14 | } | ||
15 | |||
16 | 3 | int handleWideCharScan(const char** str, const FormatSpecifierScan* fs, | |
17 | va_list args, int* countOfRead) { | ||
18 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | if (fs->assignable) { |
19 | 2 | wchar_t* toAssign = va_arg(args, wchar_t*); | |
20 | 2 | s21_size_t n = mbstowcs(toAssign, *str, 1); | |
21 | 2 | (*countOfRead)++; | |
22 | 2 | (*str) += n; | |
23 | } else { | ||
24 | 1 | s21_size_t n = mbstowcs(S21_NULL, *str, 1); | |
25 | 1 | (*str) += n; | |
26 | } | ||
27 | |||
28 | 3 | return 1; | |
29 | } | ||
30 | |||
31 | 10 | int handleIntegerAnyForm(const char** str, const FormatSpecifierScan* fs, | |
32 | va_list args, int* countOfRead) { | ||
33 | 10 | const char* p = *str; | |
34 | 10 | s21_size_t max = fs->width; | |
35 | 10 | int check = 1; | |
36 |
4/4✓ Branch 0 taken 6 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 5 times.
|
10 | if (*p == '-' || *p == '+') { |
37 | 5 | p++; | |
38 | 5 | max--; | |
39 | } | ||
40 | |||
41 |
4/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 3 times.
|
10 | if (fs->width != 0 && max == 0) { |
42 | 1 | check = 0; | |
43 |
6/6✓ Branch 0 taken 3 times.
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 3 times.
|
9 | } else if ((fs->width == 0 || max > 1) && p[0] == '0') { |
44 | 5 | p += 1; | |
45 | 5 | max -= 1; | |
46 | |||
47 |
6/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1 times.
|
5 | if ((fs->width == 0 || max > 1) && s21_strchr("Xx", p[0]) != S21_NULL) { |
48 | 3 | check = handleIntegerOrPointer(str, fs, S21_BASE_16, args, countOfRead); | |
49 | } else { | ||
50 | 2 | check = handleIntegerOrPointer(str, fs, S21_BASE_8, args, countOfRead); | |
51 | } | ||
52 | } else { | ||
53 | 4 | check = handleIntegerOrPointer(str, fs, S21_BASE_10, args, countOfRead); | |
54 | } | ||
55 | |||
56 | 10 | return check; | |
57 | } | ||
58 | |||
59 | 42 | int handleIntegerOrPointer(const char** str, const FormatSpecifierScan* fs, | |
60 | int base, va_list args, int* countOfRead) { | ||
61 | 42 | const char* start = *str; | |
62 | long long toAssign; | ||
63 | 42 | const char* end = strToLongLong(start, fs->width, base, &toAssign); | |
64 | |||
65 | 42 | int check = start != end; | |
66 | |||
67 |
4/4✓ Branch 0 taken 35 times.
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 31 times.
✓ Branch 3 taken 4 times.
|
42 | if (check && fs->assignable) { |
68 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 29 times.
|
31 | if (fs->specifier == 'p') { |
69 | 2 | void** dest = va_arg(args, void**); | |
70 | 2 | *dest = (void*)toAssign; | |
71 | 2 | (*countOfRead)++; | |
72 | } else { | ||
73 | 29 | assignInteger(fs, toAssign, args, countOfRead); | |
74 | } | ||
75 | } | ||
76 | |||
77 | 42 | *str = end; | |
78 | |||
79 | 42 | return check; | |
80 | } | ||
81 | |||
82 | 29 | void assignInteger(const FormatSpecifierScan* fs, long long toAssign, | |
83 | va_list args, int* countOfRead) { | ||
84 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 27 times.
|
29 | if (fs->length == 'h') { |
85 | 2 | short* dest = va_arg(args, short*); | |
86 | 2 | *dest = (short)toAssign; | |
87 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 26 times.
|
27 | } else if (fs->length == 'L') { |
88 | 1 | long long* dest = va_arg(args, long long*); | |
89 | 1 | *dest = toAssign; | |
90 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 24 times.
|
26 | } else if (fs->length == 'l') { |
91 | 2 | long* dest = va_arg(args, long*); | |
92 | 2 | *dest = (long)toAssign; | |
93 | } else { | ||
94 | 24 | int* dest = va_arg(args, int*); | |
95 | 24 | *dest = (int)toAssign; | |
96 | } | ||
97 | 29 | (*countOfRead)++; | |
98 | 29 | } | |
99 | |||
100 | 17 | int handleString(const char** str, const FormatSpecifierScan* fs, va_list args, | |
101 | int* countOfRead) { | ||
102 | 17 | const char* start = *str; | |
103 | 17 | s21_size_t strSize = 0; | |
104 | |||
105 |
4/4✓ Branch 0 taken 225 times.
✓ Branch 1 taken 4 times.
✓ Branch 3 taken 213 times.
✓ Branch 4 taken 12 times.
|
229 | while (**str && !charIsBlank(**str) && |
106 |
4/4✓ Branch 0 taken 202 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 1 times.
|
213 | (fs->width == 0 || strSize < fs->width)) { |
107 | 212 | (*str)++; | |
108 | 212 | strSize++; | |
109 | } | ||
110 | |||
111 |
2/2✓ Branch 0 taken 11 times.
✓ Branch 1 taken 6 times.
|
17 | if (fs->assignable) { |
112 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 9 times.
|
11 | if (fs->length == 'l') { |
113 | 2 | char* buf = malloc((strSize + 1) + sizeof(char)); | |
114 | 2 | s21_strncpy(buf, start, strSize); | |
115 | 2 | buf[strSize] = '\0'; | |
116 | |||
117 | 2 | wchar_t* dest = va_arg(args, wchar_t*); | |
118 | 2 | mbstowcs(dest, buf, strSize); | |
119 | 2 | dest[strSize] = L'\0'; | |
120 | |||
121 | 2 | free(buf); | |
122 | } else { | ||
123 | 9 | char* dest = va_arg(args, char*); | |
124 | 9 | s21_strncpy(dest, start, strSize); | |
125 | 9 | dest[strSize] = '\0'; | |
126 | } | ||
127 | |||
128 | 11 | (*countOfRead)++; | |
129 | } | ||
130 | |||
131 | 17 | return 1; | |
132 | } | ||
133 | |||
134 | 2 | int handlePercent(const char** str) { | |
135 | 2 | int check = 0; | |
136 | |||
137 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (**str == '%') { |
138 | 1 | check = 1; | |
139 | 1 | (*str)++; | |
140 | } | ||
141 | |||
142 | 2 | return check; | |
143 | } | ||
144 | |||
145 | 34 | int handleFloat(const char** str, const FormatSpecifierScan* fs, va_list args, | |
146 | int* countOfRead) { | ||
147 | 34 | const char* start = *str; | |
148 | long double toAssign; | ||
149 | 34 | const char* end = strToLongDouble(start, fs->width, &toAssign); | |
150 | |||
151 | 34 | int check = start != end; | |
152 | |||
153 |
4/4✓ Branch 0 taken 22 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 1 times.
|
34 | if (check && fs->assignable) { |
154 | 21 | assignFloat(fs, toAssign, args, countOfRead); | |
155 | } | ||
156 | |||
157 | 34 | *str = end; | |
158 | |||
159 | 34 | return check; | |
160 | } | ||
161 | |||
162 | 21 | void assignFloat(const FormatSpecifierScan* fs, long double toAssign, | |
163 | va_list args, int* countOfRead) { | ||
164 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
|
21 | if (fs->length == 'L') { |
165 | 1 | long double* dest = va_arg(args, long double*); | |
166 | 1 | *dest = toAssign; | |
167 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 18 times.
|
20 | } else if (fs->length == 'l') { |
168 | 2 | double* dest = va_arg(args, double*); | |
169 | 2 | *dest = (double)toAssign; | |
170 | } else { | ||
171 | 18 | float* dest = va_arg(args, float*); | |
172 | 18 | *dest = (float)toAssign; | |
173 | } | ||
174 | 21 | (*countOfRead)++; | |
175 | 21 | } | |
176 |