| Directory: | ./ |
|---|---|
| File: | s21_sscanf_handlers.c |
| Date: | 2025-11-01 23:04:41 |
| 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 | 39 | int handleFloat(const char** str, const FormatSpecifierScan* fs, va_list args, | |
| 146 | int* countOfRead) { | ||
| 147 | 39 | const char* start = *str; | |
| 148 | long double toAssign; | ||
| 149 | 39 | const char* end = strToLongDouble(start, fs->width, &toAssign); | |
| 150 | |||
| 151 | 39 | int check = start != end; | |
| 152 | |||
| 153 |
4/4✓ Branch 0 taken 27 times.
✓ Branch 1 taken 12 times.
✓ Branch 2 taken 26 times.
✓ Branch 3 taken 1 times.
|
39 | if (check && fs->assignable) { |
| 154 | 26 | assignFloat(fs, toAssign, args, countOfRead); | |
| 155 | } | ||
| 156 | |||
| 157 | 39 | *str = end; | |
| 158 | |||
| 159 | 39 | return check; | |
| 160 | } | ||
| 161 | |||
| 162 | 26 | 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 25 times.
|
26 | if (fs->length == 'L') { |
| 165 | 1 | long double* dest = va_arg(args, long double*); | |
| 166 | 1 | *dest = toAssign; | |
| 167 |
2/2✓ Branch 0 taken 5 times.
✓ Branch 1 taken 20 times.
|
25 | } else if (fs->length == 'l') { |
| 168 | 5 | double* dest = va_arg(args, double*); | |
| 169 | 5 | *dest = (double)toAssign; | |
| 170 | } else { | ||
| 171 | 20 | float* dest = va_arg(args, float*); | |
| 172 | 20 | *dest = (float)toAssign; | |
| 173 | } | ||
| 174 | 26 | (*countOfRead)++; | |
| 175 | 26 | } | |
| 176 |