Directory: | ./ |
---|---|
File: | s21_sscanf.c |
Date: | 2025-07-13 17:59:14 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 62 | 62 | 100.0% |
Branches: | 48 | 48 | 100.0% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | #include "s21_sscanf.h" | ||
2 | |||
3 | 94 | int s21_sscanf(const char *str, const char *format, ...) { | |
4 | va_list args; | ||
5 | 94 | va_start(args, format); | |
6 | 94 | int varsAssigned = processStr(str, str, format, args); | |
7 | 94 | va_end(args); | |
8 | 94 | return varsAssigned; | |
9 | } | ||
10 | |||
11 | 94 | int processStr(const char *startStr, const char *str, const char *format, | |
12 | va_list args) { | ||
13 | 94 | int countOfRead = 0; | |
14 | 94 | int check = 1; | |
15 |
6/6✓ Branch 0 taken 178 times.
✓ Branch 1 taken 43 times.
✓ Branch 2 taken 131 times.
✓ Branch 3 taken 47 times.
✓ Branch 4 taken 127 times.
✓ Branch 5 taken 4 times.
|
221 | while (*str && *format && check) { |
16 |
2/2✓ Branch 0 taken 118 times.
✓ Branch 1 taken 9 times.
|
127 | if (*format == '%') { |
17 | 118 | format++; | |
18 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 117 times.
|
118 | if (*format == 'n') { |
19 | 1 | int *count = va_arg(args, int *); | |
20 | 1 | *count = str - startStr; | |
21 | 1 | format++; | |
22 | } else { | ||
23 | 117 | check = parseAndProcessSpecifier(&str, &format, args, &countOfRead); | |
24 | } | ||
25 | } else { | ||
26 | 9 | check = skipChars(&str, &format); | |
27 | } | ||
28 | } | ||
29 | |||
30 |
2/2✓ Branch 1 taken 1 times.
✓ Branch 2 taken 93 times.
|
94 | if (isInvalid(str, format) == S21_EOF) { |
31 | 1 | countOfRead = S21_EOF; | |
32 | } | ||
33 | |||
34 | 94 | return countOfRead; | |
35 | } | ||
36 | |||
37 | 117 | int parseAndProcessSpecifier(const char **str, const char **format, | |
38 | va_list args, int *countOfRead) { | ||
39 | /* %[*][width][length]specifier */ | ||
40 | FormatSpecifierScan fs; | ||
41 | 117 | setAssignable(format, &fs); | |
42 | 117 | setWidth(format, &fs); | |
43 | 117 | setLength(format, &fs); | |
44 | 117 | setSpecifier(format, &fs); | |
45 | |||
46 | 117 | return processSpecifier(str, &fs, args, countOfRead); | |
47 | } | ||
48 | |||
49 | 9 | int skipChars(const char **str, const char **format) { | |
50 | 9 | int check = 1; | |
51 | |||
52 |
8/8✓ Branch 0 taken 23 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 22 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 21 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 17 times.
✓ Branch 7 taken 4 times.
|
26 | while (check && **format && **str && **format != '%') { |
53 |
2/2✓ Branch 1 taken 8 times.
✓ Branch 2 taken 9 times.
|
17 | if (charIsBlank(**format)) { |
54 | 8 | skipBlankChars(str); | |
55 | 8 | skipBlankChars(format); | |
56 | } | ||
57 | |||
58 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
|
17 | if (**format != '%') { |
59 |
2/2✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
|
14 | if (**str != **format) { |
60 | 3 | check = 0; | |
61 | } else { | ||
62 | 11 | (*str)++; | |
63 | 11 | (*format)++; | |
64 | } | ||
65 | } | ||
66 | } | ||
67 | |||
68 | 9 | return check; | |
69 | } | ||
70 | |||
71 | 117 | int processSpecifier(const char **str, const FormatSpecifierScan *fs, | |
72 | va_list args, int *countOfRead) { | ||
73 | 117 | int check = 1; | |
74 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 100 times.
|
117 | if (fs->specifier == 'c') { |
75 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
|
17 | if (fs->length != 'l') { |
76 | 14 | check = handleCharScan(str, fs, args, countOfRead); | |
77 | } else { | ||
78 | 3 | check = handleWideCharScan(str, fs, args, countOfRead); | |
79 | } | ||
80 | } else { | ||
81 | 100 | skipBlankChars(str); | |
82 | 100 | check = requireStrNotEmpty(str, countOfRead); | |
83 | |||
84 |
2/2✓ Branch 0 taken 97 times.
✓ Branch 1 taken 3 times.
|
100 | if (check) { |
85 |
4/4✓ Branch 0 taken 84 times.
✓ Branch 1 taken 13 times.
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 81 times.
|
97 | if (fs->specifier == 'd' || fs->specifier == 'u') { |
86 | 16 | check = handleIntegerOrPointer(str, fs, S21_BASE_10, args, countOfRead); | |
87 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 71 times.
|
81 | } else if (fs->specifier == 'i') { |
88 | 10 | check = handleIntegerAnyForm(str, fs, args, countOfRead); | |
89 |
2/2✓ Branch 1 taken 34 times.
✓ Branch 2 taken 37 times.
|
71 | } else if (s21_strchr("eEfgG", fs->specifier) != S21_NULL) { |
90 | 34 | check = handleFloat(str, fs, args, countOfRead); | |
91 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 31 times.
|
37 | } else if (fs->specifier == 'o') { |
92 | 6 | check = handleIntegerOrPointer(str, fs, S21_BASE_8, args, countOfRead); | |
93 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 14 times.
|
31 | } else if (fs->specifier == 's') { |
94 | 17 | check = handleString(str, fs, args, countOfRead); | |
95 |
2/2✓ Branch 1 taken 11 times.
✓ Branch 2 taken 3 times.
|
14 | } else if (s21_strchr("xXp", fs->specifier) != S21_NULL) { |
96 | 11 | check = handleIntegerOrPointer(str, fs, S21_BASE_16, args, countOfRead); | |
97 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
|
3 | } else if (fs->specifier == '%') { |
98 | 2 | check = handlePercent(str); | |
99 | } | ||
100 | } | ||
101 | } | ||
102 | |||
103 | 117 | return check; | |
104 | } | ||
105 |