1 /*
2 * Copyright (c) 2006-2025, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2025-01-04 Meco Man the first version
9 */
10
11 #include <rtklibc.h>
12 #include "utest.h"
13
TC_rt_sscanf_char(void)14 static void TC_rt_sscanf_char(void)
15 {
16 const char str[] = "A B";
17 char a, b;
18 rt_sscanf(str, "%c %c", &a, &b);
19 uassert_true(a == 'A' && b == 'B');
20 /* Move to the next character after space for the second %c */
21 rt_sscanf(str + 2, "%c", &b);
22 uassert_true(b == 'B');
23 }
24
TC_rt_sscanf_basic_int(void)25 static void TC_rt_sscanf_basic_int(void)
26 {
27 const char str[] = "12345";
28 int value;
29 int result = rt_sscanf(str, "%d", &value);
30 uassert_int_equal(result, 1);
31 uassert_int_equal(value, 12345);
32 }
33
TC_rt_sscanf_basic_float(void)34 static void TC_rt_sscanf_basic_float(void)
35 {
36 const char str[] = "123.45";
37 float value;
38 int result = rt_sscanf(str, "%f", &value);
39 uassert_int_equal(result, 1);
40 uassert_float_equal(value, 123.45);
41 }
42
TC_rt_sscanf_basic_string(void)43 static void TC_rt_sscanf_basic_string(void)
44 {
45 const char str[] = "Hello, World!";
46 char buffer[20];
47 int result = rt_sscanf(str, "%s", buffer);
48 uassert_int_equal(result, 1);
49 uassert_str_equal(buffer, "Hello,");
50 }
51
TC_rt_sscanf_string_with_space(void)52 static void TC_rt_sscanf_string_with_space(void)
53 {
54 const char str[] = "Hello World";
55 char a[20];
56 rt_sscanf(str, "%*s %s", a);
57 uassert_str_equal(a, "World");
58 }
59
TC_rt_sscanf_basic_char(void)60 static void TC_rt_sscanf_basic_char(void)
61 {
62 const char str[] = "A";
63 char value;
64 int result = rt_sscanf(str, "%c", &value);
65 uassert_int_equal(result, 1);
66 uassert_int_equal(value, 'A');
67 }
68
TC_rt_sscanf_hex_1(void)69 static void TC_rt_sscanf_hex_1(void)
70 {
71 const char str[] = "0x1A3F";
72 int value;
73 int result = rt_sscanf(str, "%x", &value);
74 uassert_int_equal(result, 1);
75 uassert_int_equal(value, 0x1A3F);
76 }
77
TC_rt_sscanf_hex_2(void)78 static void TC_rt_sscanf_hex_2(void)
79 {
80 const char str[] = "0x1A 0XFF";
81 int a, b;
82 rt_sscanf(str, "%x %x", &a, &b);
83 uassert_true(a == 0x1A && b == 0XFF);
84 }
85
TC_rt_sscanf_oct_1(void)86 static void TC_rt_sscanf_oct_1(void)
87 {
88 const char str[] = "0755";
89 int value;
90 int result = rt_sscanf(str, "%o", &value);
91 uassert_int_equal(result, 1);
92 uassert_int_equal(value, 0755);
93 }
94
TC_rt_sscanf_oct_2(void)95 static void TC_rt_sscanf_oct_2(void)
96 {
97 const char str[] = "012 077";
98 int a, b;
99 rt_sscanf(str, "%o %o", &a, &b);
100 uassert_true(a == 012 && b == 077);
101 }
102
TC_rt_sscanf_multiple_args(void)103 static void TC_rt_sscanf_multiple_args(void)
104 {
105 const char str[] = "123 Hello";
106 int int_value;
107 char str_value[20];
108 int result = rt_sscanf(str, "%d %s", &int_value, str_value);
109 uassert_int_equal(result, 2);
110 uassert_int_equal(int_value, 123);
111 uassert_str_equal(str_value, "Hello");
112 }
113
TC_rt_sscanf_pointer(void)114 static void TC_rt_sscanf_pointer(void)
115 {
116 const char str[] = "0x12345678";
117 void *ptr;
118 int result = rt_sscanf(str, "%p", &ptr);
119 uassert_int_equal(result, 1);
120 uassert_ptr_equal(ptr, (void *)0x12345678);
121 }
122
TC_rt_sscanf_width_specifier(void)123 static void TC_rt_sscanf_width_specifier(void)
124 {
125 const char str[] = "123456789";
126 int value;
127 int result = rt_sscanf(str, "%4d", &value);
128 uassert_int_equal(result, 1);
129 uassert_int_equal(value, 1234);
130 }
131
TC_rt_sscanf_suppression(void)132 static void TC_rt_sscanf_suppression(void)
133 {
134 const char str[] = "123 456";
135 int second_value;
136 int result = rt_sscanf(str, "%*d %d", &second_value);
137 uassert_int_equal(result, 1);
138 uassert_int_equal(second_value, 456);
139 }
140
TC_rt_sscanf_match_set(void)141 static void TC_rt_sscanf_match_set(void)
142 {
143 const char str[] = "abc123";
144 char buffer[10] = {0};
145 int result = rt_sscanf(str, "%[a-z]", buffer);
146 uassert_int_equal(result, 1);
147 uassert_str_equal(buffer, "abc");
148 }
149
TC_rt_sscanf_match_set_negated(void)150 static void TC_rt_sscanf_match_set_negated(void)
151 {
152 const char str[] = "abc123";
153 char buffer[10];
154 int result = rt_sscanf(str, "%[^0-9]", buffer);
155 uassert_int_equal(result, 1);
156 uassert_str_equal(buffer, "abc");
157 }
158
TC_rt_sscanf_match_set_range(void)159 static void TC_rt_sscanf_match_set_range(void)
160 {
161 const char str[] = "a-zA-Z";
162 char buffer[10];
163 int result = rt_sscanf(str, "%[a-z-A-Z]", buffer);
164 uassert_int_equal(result, 1);
165 uassert_str_equal(buffer, "a-zA-Z");
166 }
167
TC_rt_sscanf_whitespace_skip(void)168 static void TC_rt_sscanf_whitespace_skip(void)
169 {
170 const char str[] = " 12345";
171 int value;
172 int result = rt_sscanf(str, "%d", &value);
173 uassert_int_equal(result, 1);
174 uassert_int_equal(value, 12345);
175 }
176
TC_rt_sscanf_unsigned_int(void)177 static void TC_rt_sscanf_unsigned_int(void)
178 {
179 const char str[] = "4294967295";
180 unsigned int value;
181 int result = rt_sscanf(str, "%u", &value);
182 uassert_int_equal(result, 1);
183 uassert_int_equal(value, 4294967295U);
184 }
185
TC_rt_sscanf_long_long_int(void)186 static void TC_rt_sscanf_long_long_int(void)
187 {
188 const char str[] = "9223372036854775807";
189 long long value;
190 int result = rt_sscanf(str, "%lld", &value);
191 uassert_int_equal(result, 1);
192 uassert_int_equal(value, 9223372036854775807LL);
193 }
194
TC_rt_sscanf_short_int(void)195 static void TC_rt_sscanf_short_int(void)
196 {
197 const char str[] = "32767";
198 short value;
199 int result = rt_sscanf(str, "%hd", &value);
200 uassert_int_equal(result, 1);
201 uassert_int_equal(value, 32767);
202 }
203
TC_rt_sscanf_null_string(void)204 static void TC_rt_sscanf_null_string(void)
205 {
206 const char str[] = "";
207 int value;
208 int result = rt_sscanf(str, "%d", &value);
209 uassert_int_equal(result, -1);
210 }
211
212 /* https://github.com/RT-Thread/rt-thread/issues/9853 */
TC_rt_sscanf_issue_9853(void)213 static void TC_rt_sscanf_issue_9853(void)
214 {
215 int device_socket = 255;
216 int bfsz = 255;
217 const char str[] = "+MIPURC: \"rtcp\",0,240,HTTP/1.1 200 OK";
218 rt_sscanf(str, "+MIPURC:%*[^,],%d,%d", &device_socket, (int *)&bfsz);
219 uassert_int_equal(device_socket, 0);
220 uassert_int_equal(bfsz, 240);
221 }
222
utest_do_tc(void)223 static void utest_do_tc(void)
224 {
225 UTEST_UNIT_RUN(TC_rt_sscanf_char);
226 UTEST_UNIT_RUN(TC_rt_sscanf_basic_int);
227 UTEST_UNIT_RUN(TC_rt_sscanf_basic_float);
228 UTEST_UNIT_RUN(TC_rt_sscanf_basic_string);
229 UTEST_UNIT_RUN(TC_rt_sscanf_string_with_space);
230 UTEST_UNIT_RUN(TC_rt_sscanf_basic_char);
231 UTEST_UNIT_RUN(TC_rt_sscanf_hex_1);
232 UTEST_UNIT_RUN(TC_rt_sscanf_hex_2);
233 UTEST_UNIT_RUN(TC_rt_sscanf_oct_1);
234 UTEST_UNIT_RUN(TC_rt_sscanf_oct_2);
235 UTEST_UNIT_RUN(TC_rt_sscanf_multiple_args);
236 UTEST_UNIT_RUN(TC_rt_sscanf_pointer);
237 UTEST_UNIT_RUN(TC_rt_sscanf_width_specifier);
238 UTEST_UNIT_RUN(TC_rt_sscanf_suppression);
239 UTEST_UNIT_RUN(TC_rt_sscanf_match_set);
240 UTEST_UNIT_RUN(TC_rt_sscanf_match_set_negated);
241 UTEST_UNIT_RUN(TC_rt_sscanf_match_set_range);
242 UTEST_UNIT_RUN(TC_rt_sscanf_whitespace_skip);
243 UTEST_UNIT_RUN(TC_rt_sscanf_unsigned_int);
244 UTEST_UNIT_RUN(TC_rt_sscanf_long_long_int);
245 UTEST_UNIT_RUN(TC_rt_sscanf_short_int);
246 UTEST_UNIT_RUN(TC_rt_sscanf_null_string);
247 UTEST_UNIT_RUN(TC_rt_sscanf_issue_9853);
248 }
249
250 UTEST_TC_EXPORT(utest_do_tc, "klibc.rt_sscanf", RT_NULL, RT_NULL, 1000);
251