| Directory: | ./ |
|---|---|
| File: | s21_sscanf_converters.c |
| Date: | 2025-11-01 23:04:41 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 107 | 107 | 100.0% |
| Branches: | 115 | 116 | 99.1% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "s21_sscanf.h" | ||
| 2 | |||
| 3 | 42 | const char *strToLongLong(const char *start, s21_size_t n, int base, | |
| 4 | long long *toAssign) { | ||
| 5 | 42 | const char *p = start; | |
| 6 | 42 | s21_size_t max = n; | |
| 7 | 42 | int check = 1; | |
| 8 |
4/4✓ Branch 0 taken 26 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 9 times.
✓ Branch 3 taken 17 times.
|
42 | if (*p == '-' || *p == '+') { |
| 9 | 25 | p++; | |
| 10 | 25 | max--; | |
| 11 | } | ||
| 12 | |||
| 13 |
10/10✓ Branch 0 taken 14 times.
✓ Branch 1 taken 28 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 10 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 8 times.
✓ Branch 7 taken 4 times.
✓ Branch 8 taken 7 times.
✓ Branch 9 taken 1 times.
|
50 | if (base == S21_BASE_16 && (n == 0 || max > 2) && p[0] == '0' && |
| 14 | 8 | s21_strchr("xX", p[1])) { | |
| 15 | 7 | p += 2; | |
| 16 | 7 | max -= 2; | |
| 17 | } | ||
| 18 | |||
| 19 | int num; | ||
| 20 | 42 | long long result = 0; | |
| 21 |
4/4✓ Branch 1 taken 130 times.
✓ Branch 2 taken 37 times.
✓ Branch 4 taken 125 times.
✓ Branch 5 taken 5 times.
|
167 | while ((num = getHexadecimalNum(*p)) < base && isPossibleRead(n, max)) { |
| 22 | 125 | result = result * base + num; | |
| 23 | 125 | p++; | |
| 24 | 125 | max--; | |
| 25 | } | ||
| 26 | |||
| 27 |
6/6✓ Branch 0 taken 7 times.
✓ Branch 1 taken 35 times.
✓ Branch 2 taken 6 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 3 times.
|
42 | if (start + 1 == p && (*start == '+' || *start == '-')) { |
| 28 | 4 | check = 0; | |
| 29 | } | ||
| 30 | |||
| 31 |
2/2✓ Branch 0 taken 38 times.
✓ Branch 1 taken 4 times.
|
42 | if (check) { |
| 32 |
2/2✓ Branch 0 taken 13 times.
✓ Branch 1 taken 25 times.
|
38 | if (*start == '-') { |
| 33 | 13 | result *= -1; | |
| 34 | } | ||
| 35 | 38 | *toAssign = result; | |
| 36 | } else { | ||
| 37 | 4 | p = start; | |
| 38 | } | ||
| 39 | |||
| 40 | 42 | return p; | |
| 41 | } | ||
| 42 | |||
| 43 | 167 | int getHexadecimalNum(char c) { | |
| 44 | 167 | int num = 100000; | |
| 45 | |||
| 46 |
4/4✓ Branch 0 taken 142 times.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 116 times.
✓ Branch 3 taken 26 times.
|
167 | if (c >= '0' && c <= '9') { |
| 47 | 116 | num = c - '0'; | |
| 48 |
4/4✓ Branch 0 taken 14 times.
✓ Branch 1 taken 37 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 4 times.
|
51 | } else if (c >= 'a' && c <= 'f') { |
| 49 | 10 | num = 10 + c - 'a'; | |
| 50 |
4/4✓ Branch 0 taken 16 times.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 6 times.
|
41 | } else if (c >= 'A' && c <= 'F') { |
| 51 | 10 | num = 10 + c - 'A'; | |
| 52 | } | ||
| 53 | |||
| 54 | 167 | return num; | |
| 55 | } | ||
| 56 | |||
| 57 | 39 | const char *strToLongDouble(const char *start, s21_size_t n, | |
| 58 | long double *result) { | ||
| 59 | 39 | const char *p = start; | |
| 60 | 39 | s21_size_t max = n; | |
| 61 | |||
| 62 | 39 | int isEnd = 0; | |
| 63 | 39 | LongDoubleConvertation properties = {0, 0, 1, 10.0L, 0.1L, 0, 0}; | |
| 64 | |||
| 65 | 39 | long double current = 0.0L; | |
| 66 |
6/6✓ Branch 0 taken 233 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 213 times.
✓ Branch 3 taken 20 times.
✓ Branch 5 taken 210 times.
✓ Branch 6 taken 3 times.
|
249 | while (*p != '\0' && !isEnd && isPossibleRead(n, max)) { |
| 67 | 210 | isEnd = processCharLongDouble(p, start, ¤t, &properties); | |
| 68 | |||
| 69 |
2/2✓ Branch 0 taken 190 times.
✓ Branch 1 taken 20 times.
|
210 | if (!isEnd) { |
| 70 | 190 | max--; | |
| 71 | 190 | p++; | |
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 |
2/2✓ Branch 0 taken 154 times.
✓ Branch 1 taken 39 times.
|
193 | for (int i = 0; i < properties.pow10; i++) { |
| 76 | 154 | current *= properties.powMultiplier; | |
| 77 | } | ||
| 78 | |||
| 79 |
8/8✓ Branch 0 taken 15 times.
✓ Branch 1 taken 24 times.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 11 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 12 times.
✓ Branch 7 taken 1 times.
|
39 | if (p - start <= 1 && (n == 0 || max >= 3) && !properties.dot && |
| 80 |
3/4✓ Branch 0 taken 11 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 11 times.
✗ Branch 3 not taken.
|
12 | !properties.exponent && properties.countBeforeDot == 0) { |
| 81 | 11 | p = processNanAndInf(¤t, p); | |
| 82 | } | ||
| 83 | |||
| 84 |
6/6✓ Branch 0 taken 37 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 34 times.
✓ Branch 4 taken 34 times.
✓ Branch 5 taken 3 times.
|
39 | if (!isnan(current) && !isinf(current)) { |
| 85 |
4/4✓ Branch 0 taken 14 times.
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 12 times.
✓ Branch 3 taken 2 times.
|
34 | if (properties.countBeforeDot == 0 && properties.fraction == 0.1L) { |
| 86 | 12 | p = start; | |
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | 39 | *result = current * properties.sign; | |
| 91 | |||
| 92 | 39 | return p; | |
| 93 | } | ||
| 94 | |||
| 95 | 210 | int processCharLongDouble(const char *p, const char *start, | |
| 96 | long double *current, | ||
| 97 | LongDoubleConvertation *properties) { | ||
| 98 | 210 | int isEnd = 0; | |
| 99 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 196 times.
|
210 | if (s21_strchr("+-", *p)) { |
| 100 | 14 | isEnd = processSignLongDouble(start, p, properties); | |
| 101 |
6/6✓ Branch 0 taken 25 times.
✓ Branch 1 taken 171 times.
✓ Branch 2 taken 24 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 23 times.
✓ Branch 5 taken 1 times.
|
196 | } else if (*p == '.' && !properties->exponent && !properties->dot) { |
| 102 | 23 | properties->dot = 1; | |
| 103 |
4/4✓ Branch 1 taken 10 times.
✓ Branch 2 taken 163 times.
✓ Branch 3 taken 9 times.
✓ Branch 4 taken 1 times.
|
173 | } else if (s21_strchr("eE", *p) && !properties->exponent) { |
| 104 | 9 | properties->exponent = 1; | |
| 105 |
4/4✓ Branch 0 taken 159 times.
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 145 times.
✓ Branch 3 taken 14 times.
|
164 | } else if (*p >= '0' && *p <= '9') { |
| 106 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 131 times.
|
145 | if (properties->exponent) { |
| 107 | 14 | properties->pow10 = properties->pow10 * 10 + (*p - '0'); | |
| 108 | } else { | ||
| 109 | 131 | processNumLongDouble(current, *p - '0', properties); | |
| 110 | } | ||
| 111 | } else { | ||
| 112 | 19 | isEnd = 1; | |
| 113 | } | ||
| 114 | 210 | return isEnd; | |
| 115 | } | ||
| 116 | |||
| 117 | 14 | int processSignLongDouble(const char *start, const char *p, | |
| 118 | LongDoubleConvertation *properties) { | ||
| 119 | 14 | int isEnd = 0; | |
| 120 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 4 times.
|
14 | if (start == p) { |
| 121 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 1 times.
|
10 | if (*p == '-') { |
| 122 | 9 | properties->sign = -1; | |
| 123 | } else { | ||
| 124 | 1 | properties->sign = 1; | |
| 125 | } | ||
| 126 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
|
4 | } else if (s21_strchr("Ee", *(p - 1))) { |
| 127 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
|
3 | if (*p == '-') { |
| 128 | 1 | properties->powMultiplier = 0.1l; | |
| 129 | } else { | ||
| 130 | 2 | properties->powMultiplier = 10.0l; | |
| 131 | } | ||
| 132 | } else { | ||
| 133 | 1 | isEnd = 1; | |
| 134 | } | ||
| 135 | |||
| 136 | 14 | return isEnd; | |
| 137 | } | ||
| 138 | |||
| 139 | 131 | void processNumLongDouble(long double *current, int num, | |
| 140 | LongDoubleConvertation *properties) { | ||
| 141 |
2/2✓ Branch 0 taken 98 times.
✓ Branch 1 taken 33 times.
|
131 | if (properties->dot) { |
| 142 | 98 | *current = (*current) + (properties->fraction) * num; | |
| 143 | 98 | properties->fraction *= 0.1L; | |
| 144 | } else { | ||
| 145 | 33 | *current = (*current) * 10.0l + num; | |
| 146 | 33 | properties->countBeforeDot++; | |
| 147 | } | ||
| 148 | 131 | } | |
| 149 | |||
| 150 | 11 | const char *processNanAndInf(long double *result, const char *p) { | |
| 151 |
2/2✓ Branch 1 taken 3 times.
✓ Branch 2 taken 8 times.
|
11 | if (isInf(p)) { |
| 152 | 3 | *result = 1.0l / 0.0l; | |
| 153 | 3 | p += 3; | |
| 154 |
2/2✓ Branch 1 taken 2 times.
✓ Branch 2 taken 6 times.
|
8 | } else if (isNan(p)) { |
| 155 | 2 | *result = S21_NAN; | |
| 156 | 2 | p += 3; | |
| 157 | } | ||
| 158 | |||
| 159 | 11 | return p; | |
| 160 | } | ||
| 161 | |||
| 162 | 11 | int isInf(const char *p) { | |
| 163 | 11 | int check = 0; | |
| 164 | |||
| 165 |
6/6✓ Branch 1 taken 6 times.
✓ Branch 2 taken 5 times.
✓ Branch 4 taken 5 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 3 times.
✓ Branch 7 taken 2 times.
|
16 | if (s21_strchr("iI", p[0]) && s21_strchr("nN", p[1]) && |
| 166 | 5 | s21_strchr("fF", p[2])) { | |
| 167 | 3 | check = 1; | |
| 168 | } | ||
| 169 | |||
| 170 | 11 | return check; | |
| 171 | } | ||
| 172 | |||
| 173 | 8 | int isNan(const char *p) { | |
| 174 | 8 | int check = 0; | |
| 175 | |||
| 176 |
6/6✓ Branch 1 taken 4 times.
✓ Branch 2 taken 4 times.
✓ Branch 4 taken 3 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 1 times.
|
11 | if (s21_strchr("Nn", p[0]) && s21_strchr("aA", p[1]) && |
| 177 | 3 | s21_strchr("Nn", p[2])) { | |
| 178 | 2 | check = 1; | |
| 179 | } | ||
| 180 | |||
| 181 | 8 | return check; | |
| 182 | } | ||
| 183 |