]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2019 Nicira, Inc. | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at: | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | */ | |
16 | ||
17 | #include <config.h> | |
18 | #undef NDEBUG | |
19 | #include "util.h" | |
20 | #include <assert.h> | |
21 | #include <getopt.h> | |
22 | #include <inttypes.h> | |
23 | #include <limits.h> | |
24 | #include <stdio.h> | |
25 | #include <stdlib.h> | |
26 | #include "byte-order.h" | |
27 | #include "command-line.h" | |
28 | #include "ovstest.h" | |
29 | #include "random.h" | |
30 | #include "sat-math.h" | |
31 | #include "openvswitch/vlog.h" | |
32 | ||
33 | static void | |
34 | check_log_2_floor(uint32_t x, int n) | |
35 | { | |
36 | if (log_2_floor(x) != n) { | |
37 | fprintf(stderr, "log_2_floor(%"PRIu32") is %d but should be %d\n", | |
38 | x, log_2_floor(x), n); | |
39 | abort(); | |
40 | } | |
41 | } | |
42 | ||
43 | static void | |
44 | test_log_2_floor(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
45 | { | |
46 | int n; | |
47 | ||
48 | for (n = 0; n < 32; n++) { | |
49 | /* Check minimum x such that f(x) == n. */ | |
50 | check_log_2_floor(1 << n, n); | |
51 | ||
52 | /* Check maximum x such that f(x) == n. */ | |
53 | check_log_2_floor((1 << n) | ((1 << n) - 1), n); | |
54 | ||
55 | /* Check a random value in the middle. */ | |
56 | check_log_2_floor((random_uint32() & ((1 << n) - 1)) | (1 << n), n); | |
57 | } | |
58 | ||
59 | /* log_2_floor(0) is undefined, so don't check it. */ | |
60 | } | |
61 | ||
62 | static void | |
63 | check_ctz32(uint32_t x, int n) | |
64 | { | |
65 | if (ctz32(x) != n) { | |
66 | fprintf(stderr, "ctz32(%"PRIu32") is %d but should be %d\n", | |
67 | x, ctz32(x), n); | |
68 | abort(); | |
69 | } | |
70 | } | |
71 | ||
72 | static void | |
73 | check_ctz64(uint64_t x, int n) | |
74 | { | |
75 | if (ctz64(x) != n) { | |
76 | fprintf(stderr, "ctz64(%"PRIu64") is %d but should be %d\n", | |
77 | x, ctz64(x), n); | |
78 | abort(); | |
79 | } | |
80 | } | |
81 | ||
82 | static void | |
83 | test_ctz(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
84 | { | |
85 | int n; | |
86 | ||
87 | for (n = 0; n < 32; n++) { | |
88 | /* Check minimum x such that f(x) == n. */ | |
89 | check_ctz32(1 << n, n); | |
90 | ||
91 | /* Check maximum x such that f(x) == n. */ | |
92 | check_ctz32(UINT32_MAX << n, n); | |
93 | ||
94 | /* Check a random value in the middle. */ | |
95 | check_ctz32((random_uint32() | 1) << n, n); | |
96 | } | |
97 | ||
98 | ||
99 | for (n = 0; n < 64; n++) { | |
100 | /* Check minimum x such that f(x) == n. */ | |
101 | check_ctz64(UINT64_C(1) << n, n); | |
102 | ||
103 | /* Check maximum x such that f(x) == n. */ | |
104 | check_ctz64(UINT64_MAX << n, n); | |
105 | ||
106 | /* Check a random value in the middle. */ | |
107 | check_ctz64((random_uint64() | UINT64_C(1)) << n, n); | |
108 | } | |
109 | ||
110 | /* Check ctz(0). */ | |
111 | check_ctz32(0, 32); | |
112 | check_ctz64(0, 64); | |
113 | } | |
114 | ||
115 | static void | |
116 | check_clz32(uint32_t x, int n) | |
117 | { | |
118 | if (clz32(x) != n) { | |
119 | fprintf(stderr, "clz32(%"PRIu32") is %d but should be %d\n", | |
120 | x, clz32(x), n); | |
121 | abort(); | |
122 | } | |
123 | } | |
124 | ||
125 | static void | |
126 | check_clz64(uint64_t x, int n) | |
127 | { | |
128 | if (clz64(x) != n) { | |
129 | fprintf(stderr, "clz64(%"PRIu64") is %d but should be %d\n", | |
130 | x, clz64(x), n); | |
131 | abort(); | |
132 | } | |
133 | } | |
134 | ||
135 | static void | |
136 | test_clz(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
137 | { | |
138 | int n; | |
139 | ||
140 | for (n = 0; n < 32; n++) { | |
141 | /* Check minimum x such that f(x) == n. */ | |
142 | check_clz32((1u << 31) >> n, n); | |
143 | ||
144 | /* Check maximum x such that f(x) == n. */ | |
145 | check_clz32(UINT32_MAX >> n, n); | |
146 | ||
147 | /* Check a random value in the middle. */ | |
148 | check_clz32((random_uint32() | 1u << 31) >> n, n); | |
149 | } | |
150 | ||
151 | for (n = 0; n < 64; n++) { | |
152 | /* Check minimum x such that f(x) == n. */ | |
153 | check_clz64((UINT64_C(1) << 63) >> n, n); | |
154 | ||
155 | /* Check maximum x such that f(x) == n. */ | |
156 | check_clz64(UINT64_MAX >> n, n); | |
157 | ||
158 | /* Check a random value in the middle. */ | |
159 | check_clz64((random_uint64() | UINT64_C(1) << 63) >> n, n); | |
160 | } | |
161 | ||
162 | /* Check clz(0). */ | |
163 | check_clz32(0, 32); | |
164 | check_clz64(0, 64); | |
165 | } | |
166 | ||
167 | /* Returns a random number in the range 'min'...'max' inclusive. */ | |
168 | static uint32_t | |
169 | random_in_range(uint32_t min, uint32_t max) | |
170 | { | |
171 | return min == max ? min : min + random_range(max - min + 1); | |
172 | } | |
173 | ||
174 | static void | |
175 | check_rup2(uint32_t x, int n) | |
176 | { | |
177 | uint32_t rup2 = ROUND_UP_POW2(x); | |
178 | if (rup2 != n) { | |
179 | fprintf(stderr, "ROUND_UP_POW2(%#"PRIx32") is %#"PRIx32" " | |
180 | "but should be %#"PRIx32"\n", x, rup2, n); | |
181 | abort(); | |
182 | } | |
183 | } | |
184 | ||
185 | static void | |
186 | test_round_up_pow2(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
187 | { | |
188 | int n; | |
189 | ||
190 | for (n = 0; n < 32; n++) { | |
191 | /* Min, max value for which ROUND_UP_POW2 should yield (1 << n). */ | |
192 | uint32_t min = ((1u << n) >> 1) + 1; | |
193 | uint32_t max = 1u << n; | |
194 | ||
195 | check_rup2(min, 1u << n); | |
196 | check_rup2(max, 1u << n); | |
197 | check_rup2(random_in_range(min, max), 1u << n); | |
198 | } | |
199 | check_rup2(0, 0); | |
200 | } | |
201 | ||
202 | static void | |
203 | check_rdp2(uint32_t x, int n) | |
204 | { | |
205 | uint32_t rdp2 = ROUND_DOWN_POW2(x); | |
206 | if (rdp2 != n) { | |
207 | fprintf(stderr, "ROUND_DOWN_POW2(%#"PRIx32") is %#"PRIx32" " | |
208 | "but should be %#"PRIx32"\n", x, rdp2, n); | |
209 | abort(); | |
210 | } | |
211 | } | |
212 | ||
213 | static void | |
214 | test_round_down_pow2(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
215 | { | |
216 | int n; | |
217 | ||
218 | for (n = 0; n < 32; n++) { | |
219 | /* Min, max value for which ROUND_DOWN_POW2 should yield (1 << n). */ | |
220 | uint32_t min = 1u << n; | |
221 | uint32_t max = ((1u << n) << 1) - 1; | |
222 | ||
223 | check_rdp2(min, 1u << n); | |
224 | check_rdp2(max, 1u << n); | |
225 | check_rdp2(random_in_range(min, max), 1u << n); | |
226 | } | |
227 | check_rdp2(0, 0); | |
228 | } | |
229 | ||
230 | static void | |
231 | shuffle(uint64_t *p, size_t n) | |
232 | { | |
233 | for (; n > 1; n--, p++) { | |
234 | uint64_t *q = &p[random_range(n)]; | |
235 | uint64_t tmp = *p; | |
236 | *p = *q; | |
237 | *q = tmp; | |
238 | } | |
239 | } | |
240 | ||
241 | static void | |
242 | check_count_1bits(uint64_t x, int n) | |
243 | { | |
244 | if (count_1bits(x) != n) { | |
245 | fprintf(stderr, "count_1bits(%#"PRIx64") is %d but should be %d\n", | |
246 | x, count_1bits(x), n); | |
247 | abort(); | |
248 | } | |
249 | } | |
250 | ||
251 | static void | |
252 | test_count_1bits(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
253 | { | |
254 | uint64_t bits[64]; | |
255 | int i; | |
256 | ||
257 | for (i = 0; i < ARRAY_SIZE(bits); i++) { | |
258 | bits[i] = UINT64_C(1) << i; | |
259 | } | |
260 | ||
261 | check_count_1bits(0, 0); | |
262 | ||
263 | for (i = 0; i < 1000; i++) { | |
264 | uint64_t x = 0; | |
265 | int j; | |
266 | ||
267 | shuffle(bits, ARRAY_SIZE(bits)); | |
268 | for (j = 0; j < 64; j++) { | |
269 | x |= bits[j]; | |
270 | check_count_1bits(x, j + 1); | |
271 | } | |
272 | assert(x == UINT64_MAX); | |
273 | ||
274 | shuffle(bits, ARRAY_SIZE(bits)); | |
275 | for (j = 63; j >= 0; j--) { | |
276 | x &= ~bits[j]; | |
277 | check_count_1bits(x, j); | |
278 | } | |
279 | assert(x == 0); | |
280 | } | |
281 | } | |
282 | ||
283 | /* Returns the sum of the squares of the first 'n' positive integers. */ | |
284 | static unsigned int | |
285 | sum_of_squares(int n) | |
286 | { | |
287 | return n * (n + 1) * (2 * n + 1) / 6; | |
288 | } | |
289 | ||
290 | static void | |
291 | test_bitwise_copy(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
292 | { | |
293 | unsigned int n_loops; | |
294 | int src_ofs; | |
295 | int dst_ofs; | |
296 | int n_bits; | |
297 | ||
298 | n_loops = 0; | |
299 | for (n_bits = 0; n_bits <= 64; n_bits++) { | |
300 | for (src_ofs = 0; src_ofs < 64 - n_bits; src_ofs++) { | |
301 | for (dst_ofs = 0; dst_ofs < 64 - n_bits; dst_ofs++) { | |
302 | ovs_be64 src = htonll(random_uint64()); | |
303 | ovs_be64 dst = htonll(random_uint64()); | |
304 | ovs_be64 orig_dst = dst; | |
305 | ovs_be64 expect; | |
306 | ||
307 | if (n_bits == 64) { | |
308 | expect = dst; | |
309 | } else { | |
310 | uint64_t mask = (UINT64_C(1) << n_bits) - 1; | |
311 | expect = orig_dst & ~htonll(mask << dst_ofs); | |
312 | expect |= htonll(((ntohll(src) >> src_ofs) & mask) | |
313 | << dst_ofs); | |
314 | } | |
315 | ||
316 | bitwise_copy(&src, sizeof src, src_ofs, | |
317 | &dst, sizeof dst, dst_ofs, | |
318 | n_bits); | |
319 | if (expect != dst) { | |
320 | fprintf(stderr,"copy_bits(0x%016"PRIx64",8,%d, " | |
321 | "0x%016"PRIx64",8,%d, %d) yielded 0x%016"PRIx64" " | |
322 | "instead of the expected 0x%016"PRIx64"\n", | |
323 | ntohll(src), src_ofs, | |
324 | ntohll(orig_dst), dst_ofs, | |
325 | n_bits, | |
326 | ntohll(dst), ntohll(expect)); | |
327 | abort(); | |
328 | } | |
329 | ||
330 | n_loops++; | |
331 | } | |
332 | } | |
333 | } | |
334 | ||
335 | if (n_loops != sum_of_squares(64)) { | |
336 | abort(); | |
337 | } | |
338 | } | |
339 | ||
340 | static void | |
341 | test_bitwise_zero(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
342 | { | |
343 | unsigned int n_loops; | |
344 | int dst_ofs; | |
345 | int n_bits; | |
346 | ||
347 | n_loops = 0; | |
348 | for (n_bits = 0; n_bits <= 64; n_bits++) { | |
349 | for (dst_ofs = 0; dst_ofs < 64 - n_bits; dst_ofs++) { | |
350 | ovs_be64 dst = htonll(random_uint64()); | |
351 | ovs_be64 orig_dst = dst; | |
352 | ovs_be64 expect; | |
353 | ||
354 | if (n_bits == 64) { | |
355 | expect = htonll(0); | |
356 | } else { | |
357 | uint64_t mask = (UINT64_C(1) << n_bits) - 1; | |
358 | expect = orig_dst & ~htonll(mask << dst_ofs); | |
359 | } | |
360 | ||
361 | bitwise_zero(&dst, sizeof dst, dst_ofs, n_bits); | |
362 | if (expect != dst) { | |
363 | fprintf(stderr,"bitwise_zero(0x%016"PRIx64",8,%d, %d) " | |
364 | "yielded 0x%016"PRIx64" " | |
365 | "instead of the expected 0x%016"PRIx64"\n", | |
366 | ntohll(orig_dst), dst_ofs, | |
367 | n_bits, | |
368 | ntohll(dst), ntohll(expect)); | |
369 | abort(); | |
370 | } | |
371 | ||
372 | n_loops++; | |
373 | } | |
374 | } | |
375 | ||
376 | if (n_loops != 64 * (64 + 1) / 2) { | |
377 | abort(); | |
378 | } | |
379 | } | |
380 | ||
381 | static void | |
382 | test_bitwise_one(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
383 | { | |
384 | unsigned int n_loops; | |
385 | int dst_ofs; | |
386 | int n_bits; | |
387 | ||
388 | n_loops = 0; | |
389 | for (n_bits = 0; n_bits <= 64; n_bits++) { | |
390 | for (dst_ofs = 0; dst_ofs < 64 - n_bits; dst_ofs++) { | |
391 | ovs_be64 dst = htonll(random_uint64()); | |
392 | ovs_be64 orig_dst = dst; | |
393 | ovs_be64 expect; | |
394 | ||
395 | if (n_bits == 64) { | |
396 | expect = OVS_BE64_MAX; | |
397 | } else { | |
398 | uint64_t mask = (UINT64_C(1) << n_bits) - 1; | |
399 | expect = orig_dst | htonll(mask << dst_ofs); | |
400 | } | |
401 | ||
402 | bitwise_one(&dst, sizeof dst, dst_ofs, n_bits); | |
403 | if (expect != dst) { | |
404 | fprintf(stderr,"bitwise_one(0x%016"PRIx64",8,%d, %d) " | |
405 | "yielded 0x%016"PRIx64" " | |
406 | "instead of the expected 0x%016"PRIx64"\n", | |
407 | ntohll(orig_dst), dst_ofs, | |
408 | n_bits, | |
409 | ntohll(dst), ntohll(expect)); | |
410 | abort(); | |
411 | } | |
412 | ||
413 | n_loops++; | |
414 | } | |
415 | } | |
416 | ||
417 | if (n_loops != 64 * (64 + 1) / 2) { | |
418 | abort(); | |
419 | } | |
420 | } | |
421 | ||
422 | static void | |
423 | test_bitwise_is_all_zeros(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
424 | { | |
425 | int n_loops; | |
426 | ||
427 | for (n_loops = 0; n_loops < 100; n_loops++) { | |
428 | ovs_be64 x = htonll(0); | |
429 | int i; | |
430 | ||
431 | for (i = 0; i < 64; i++) { | |
432 | ovs_be64 bit; | |
433 | int ofs, n; | |
434 | ||
435 | /* Change a random 0-bit into a 1-bit. */ | |
436 | do { | |
437 | bit = htonll(UINT64_C(1) << (random_range(64))); | |
438 | } while (x & bit); | |
439 | x |= bit; | |
440 | ||
441 | for (ofs = 0; ofs < 64; ofs++) { | |
442 | for (n = 0; n <= 64 - ofs; n++) { | |
443 | bool expect; | |
444 | bool answer; | |
445 | ||
446 | expect = (n == 64 | |
447 | ? x == 0 | |
448 | : !(x & htonll(((UINT64_C(1) << n) - 1) | |
449 | << ofs))); | |
450 | answer = bitwise_is_all_zeros(&x, sizeof x, ofs, n); | |
451 | if (expect != answer) { | |
452 | fprintf(stderr, | |
453 | "bitwise_is_all_zeros(0x%016"PRIx64",8,%d,%d " | |
454 | "returned %s instead of %s\n", | |
455 | ntohll(x), ofs, n, | |
456 | answer ? "true" : "false", | |
457 | expect ? "true" : "false"); | |
458 | abort(); | |
459 | } | |
460 | } | |
461 | } | |
462 | } | |
463 | } | |
464 | } | |
465 | ||
466 | static int | |
467 | trivial_bitwise_rscan(const void *p, unsigned int len, bool target, | |
468 | int start, int end) | |
469 | { | |
470 | int ofs; | |
471 | ||
472 | for (ofs = start; ofs > end; ofs--) { | |
473 | if (bitwise_get_bit(p, len, ofs) == target) { | |
474 | break; | |
475 | } | |
476 | } | |
477 | return ofs; | |
478 | } | |
479 | ||
480 | static void | |
481 | test_bitwise_rscan(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
482 | { | |
483 | /* All 1s */ | |
484 | uint8_t s1[3] = {0xff, 0xff, 0xff}; | |
485 | /* Target is the first bit */ | |
486 | ovs_assert(23 == bitwise_rscan(s1, 3, 1, 23, -1)); | |
487 | /* Target is not found, return -1 */ | |
488 | ovs_assert(-1 == bitwise_rscan(s1, 3, 0, 23, -1)); | |
489 | /* Target is not found and end != -1, return end */ | |
490 | ovs_assert(20 == bitwise_rscan(s1, 3, 0, 23, 20)); | |
491 | ||
492 | /* bit 20 - 23 are 0s */ | |
493 | uint8_t s2[3] = {0x0f, 0xff, 0xff}; | |
494 | /* Target is in the first byte but not the first bit */ | |
495 | ovs_assert(19 == bitwise_rscan(s2, 3, 1, 23, -1)); | |
496 | /* Target exists before the start postion */ | |
497 | ovs_assert(18 == bitwise_rscan(s2, 3, 1, 18, -1)); | |
498 | /* Target exists after the end postion, return end */ | |
499 | ovs_assert(20 == bitwise_rscan(s2, 3, 1, 23, 20)); | |
500 | /* Target is at the end postion, return end */ | |
501 | ovs_assert(19 == bitwise_rscan(s2, 3, 1, 23, 19)); | |
502 | /* start == end, target at start */ | |
503 | ovs_assert(19 == bitwise_rscan(s2, 3, 1, 19, 19)); | |
504 | /* start == end, target not at start */ | |
505 | ovs_assert(20 == bitwise_rscan(s2, 3, 1, 20, 20)); | |
506 | /* Target is 0 ... */ | |
507 | ovs_assert(22 == bitwise_rscan(s2, 3, 0, 22, -1)); | |
508 | ||
509 | /* bit 4 - 23 are 0s */ | |
510 | uint8_t s3[3] = {0x00, 0x00, 0x0f}; | |
511 | /* Target is in the end byte */ | |
512 | ovs_assert(3 == bitwise_rscan(s3, 3, 1, 16, -1)); | |
513 | /* Target exists after the end byte, return end */ | |
514 | ovs_assert(15 == bitwise_rscan(s3, 3, 1, 23, 15)); | |
515 | /* Target exists in end byte but after the end bit, return end */ | |
516 | ovs_assert(4 == bitwise_rscan(s3, 3, 1, 23, 4)); | |
517 | /* Target is 0 ... */ | |
518 | ovs_assert(12 == bitwise_rscan(s3, 3, 0, 12, -1)); | |
519 | ||
520 | /* All 0s */ | |
521 | uint8_t s4[3] = {0x00, 0x00, 0x00}; | |
522 | /* Target not found */ | |
523 | ovs_assert(-1 == bitwise_rscan(s4, 3, 1, 23, -1)); | |
524 | /* Target is 0 ..., start is 0 */ | |
525 | ovs_assert(0 == bitwise_rscan(s4, 3, 0, 0, -1)); | |
526 | ||
527 | int n_loops; | |
528 | for (n_loops = 0; n_loops < 100; n_loops++) { | |
529 | ovs_be64 x = htonll(0); | |
530 | int i; | |
531 | ||
532 | for (i = 0; i < 64; i++) { | |
533 | ovs_be64 bit; | |
534 | ||
535 | /* Change a random 0-bit into a 1-bit. */ | |
536 | do { | |
537 | bit = htonll(UINT64_C(1) << (random_range(64))); | |
538 | } while (x & bit); | |
539 | x |= bit; | |
540 | ||
541 | for (int end = -1; end <= 63; end++) { | |
542 | for (int start = end; start <= 63; start++) { | |
543 | for (int target = 0; target < 2; target++) { | |
544 | bool expect = trivial_bitwise_rscan( | |
545 | &x, sizeof x, target, start, end); | |
546 | bool answer = bitwise_rscan( | |
547 | &x, sizeof x, target, start, end); | |
548 | if (expect != answer) { | |
549 | fprintf(stderr, | |
550 | "bitwise_rscan(0x%016"PRIx64",8,%s,%d,%d) " | |
551 | "returned %s instead of %s\n", | |
552 | ntohll(x), | |
553 | target ? "true" : "false", | |
554 | start, end, | |
555 | answer ? "true" : "false", | |
556 | expect ? "true" : "false"); | |
557 | abort(); | |
558 | } | |
559 | } | |
560 | } | |
561 | } | |
562 | } | |
563 | } | |
564 | } | |
565 | ||
566 | static void | |
567 | test_follow_symlinks(struct ovs_cmdl_context *ctx) | |
568 | { | |
569 | int i; | |
570 | ||
571 | for (i = 1; i < ctx->argc; i++) { | |
572 | char *target = follow_symlinks(ctx->argv[i]); | |
573 | puts(target); | |
574 | free(target); | |
575 | } | |
576 | } | |
577 | ||
578 | static void | |
579 | test_assert(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
580 | { | |
581 | ovs_assert(false); | |
582 | } | |
583 | ||
584 | static void | |
585 | test_ovs_scan(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
586 | { | |
587 | char str[16], str2[16], str3[16]; | |
588 | long double ld, ld2; | |
589 | long long ll, ll2; | |
590 | signed char c, c2; | |
591 | ptrdiff_t pd, pd2; | |
592 | intmax_t im, im2; | |
593 | size_t sz, sz2; | |
594 | int n, n2, n3; | |
595 | double d, d2; | |
596 | short s, s2; | |
597 | float f, f2; | |
598 | long l, l2; | |
599 | int i, i2; | |
600 | ||
601 | ovs_assert(ovs_scan("", " ")); | |
602 | ovs_assert(ovs_scan(" ", " ")); | |
603 | ovs_assert(ovs_scan(" ", " ")); | |
604 | ovs_assert(ovs_scan(" \t ", " ")); | |
605 | ||
606 | ovs_assert(ovs_scan("xyzzy", "xyzzy")); | |
607 | ovs_assert(ovs_scan("xy%zzy", "xy%%zzy")); | |
608 | ovs_assert(!ovs_scan(" xy%zzy", "xy%%zzy")); | |
609 | ovs_assert(ovs_scan(" xy%\tzzy", " xy%% zzy")); | |
610 | ||
611 | ovs_assert(ovs_scan("123", "%d", &i)); | |
612 | ovs_assert(i == 123); | |
613 | ovs_assert(ovs_scan("0", "%d", &i)); | |
614 | ovs_assert(i == 0); | |
615 | ovs_assert(!ovs_scan("123", "%d%d", &i, &i2)); | |
616 | ovs_assert(ovs_scan("+123", "%d", &i)); | |
617 | ovs_assert(i == 123); | |
618 | ovs_assert(ovs_scan("-123", "%d", &i)); | |
619 | ovs_assert(i == -123); | |
620 | ovs_assert(ovs_scan("0123", "%d", &i)); | |
621 | ovs_assert(i == 123); | |
622 | ovs_assert(ovs_scan(" 123", "%d", &i)); | |
623 | ovs_assert(i == 123); | |
624 | ovs_assert(ovs_scan("0x123", "%d", &i)); | |
625 | ovs_assert(i == 0); | |
626 | ovs_assert(ovs_scan("123", "%2d %d", &i, &i2)); | |
627 | ovs_assert(i == 12); | |
628 | ovs_assert(i2 == 3); | |
629 | ovs_assert(ovs_scan("+123", "%2d %d", &i, &i2)); | |
630 | ovs_assert(i == 1); | |
631 | ovs_assert(i2 == 23); | |
632 | ovs_assert(ovs_scan("-123", "%2d %d", &i, &i2)); | |
633 | ovs_assert(i == -1); | |
634 | ovs_assert(i2 == 23); | |
635 | ovs_assert(ovs_scan("0123", "%2d %d", &i, &i2)); | |
636 | ovs_assert(i == 1); | |
637 | ovs_assert(i2 == 23); | |
638 | ovs_assert(ovs_scan("123", "%*2d %d", &i)); | |
639 | ovs_assert(i == 3); | |
640 | ovs_assert(ovs_scan("+123", "%2d %*d", &i)); | |
641 | ovs_assert(i == 1); | |
642 | ovs_assert(i2 == 23); | |
643 | ovs_assert(ovs_scan("-123", "%*2d %*d")); | |
644 | ||
645 | ovs_assert(ovs_scan("123", "%u", &i)); | |
646 | ovs_assert(i == 123); | |
647 | ovs_assert(ovs_scan("0", "%u", &i)); | |
648 | ovs_assert(i == 0); | |
649 | ovs_assert(!ovs_scan("123", "%u%u", &i, &i2)); | |
650 | ovs_assert(ovs_scan("+123", "%u", &i)); | |
651 | ovs_assert(i == 123); | |
652 | ovs_assert(ovs_scan("-123", "%u", &i)); | |
653 | ovs_assert(i == -123); | |
654 | ovs_assert(ovs_scan("0123", "%u", &i)); | |
655 | ovs_assert(i == 123); | |
656 | ovs_assert(ovs_scan(" 123", "%u", &i)); | |
657 | ovs_assert(i == 123); | |
658 | ovs_assert(ovs_scan("0x123", "%u", &i)); | |
659 | ovs_assert(i == 0); | |
660 | ovs_assert(ovs_scan("123", "%2u %u", &i, &i2)); | |
661 | ovs_assert(i == 12); | |
662 | ovs_assert(i2 == 3); | |
663 | ovs_assert(ovs_scan("+123", "%2u %u", &i, &i2)); | |
664 | ovs_assert(i == 1); | |
665 | ovs_assert(i2 == 23); | |
666 | ovs_assert(ovs_scan("-123", "%2u %u", &i, &i2)); | |
667 | ovs_assert(i == -1); | |
668 | ovs_assert(i2 == 23); | |
669 | ovs_assert(ovs_scan("0123", "%2u %u", &i, &i2)); | |
670 | ovs_assert(i == 1); | |
671 | ovs_assert(i2 == 23); | |
672 | ovs_assert(ovs_scan("123", "%*2u %u", &i)); | |
673 | ovs_assert(i == 3); | |
674 | ovs_assert(ovs_scan("+123", "%2u %*u", &i)); | |
675 | ovs_assert(i == 1); | |
676 | ovs_assert(i2 == 23); | |
677 | ovs_assert(ovs_scan("-123", "%*2u %*u")); | |
678 | ||
679 | ovs_assert(ovs_scan("123", "%i", &i)); | |
680 | ovs_assert(i == 123); | |
681 | ovs_assert(ovs_scan("0", "%i", &i)); | |
682 | ovs_assert(i == 0); | |
683 | ovs_assert(!ovs_scan("123", "%i%i", &i, &i2)); | |
684 | ovs_assert(ovs_scan("+123", "%i", &i)); | |
685 | ovs_assert(i == 123); | |
686 | ovs_assert(ovs_scan("-123", "%i", &i)); | |
687 | ovs_assert(i == -123); | |
688 | ovs_assert(ovs_scan("0123", "%i", &i)); | |
689 | ovs_assert(i == 0123); | |
690 | ovs_assert(ovs_scan(" 123", "%i", &i)); | |
691 | ovs_assert(i == 123); | |
692 | ovs_assert(ovs_scan("0x123", "%i", &i)); | |
693 | ovs_assert(i == 0x123); | |
694 | ovs_assert(ovs_scan("123", "%2i %i", &i, &i2)); | |
695 | ovs_assert(i == 12); | |
696 | ovs_assert(i2 == 3); | |
697 | ovs_assert(ovs_scan("+123", "%2i %i", &i, &i2)); | |
698 | ovs_assert(i == 1); | |
699 | ovs_assert(i2 == 23); | |
700 | ovs_assert(ovs_scan("-123", "%2i %i", &i, &i2)); | |
701 | ovs_assert(i == -1); | |
702 | ovs_assert(i2 == 23); | |
703 | ovs_assert(ovs_scan("0123", "%2i %i", &i, &i2)); | |
704 | ovs_assert(i == 1); | |
705 | ovs_assert(i2 == 23); | |
706 | ovs_assert(ovs_scan("123", "%*2i %i", &i)); | |
707 | ovs_assert(i == 3); | |
708 | ovs_assert(ovs_scan("+123", "%2i %*i", &i)); | |
709 | ovs_assert(i == 1); | |
710 | ovs_assert(i2 == 23); | |
711 | ovs_assert(ovs_scan("-123", "%*2i %*i")); | |
712 | ||
713 | ovs_assert(ovs_scan("123", "%o", &i)); | |
714 | ovs_assert(i == 0123); | |
715 | ovs_assert(ovs_scan("0", "%o", &i)); | |
716 | ovs_assert(i == 0); | |
717 | ovs_assert(!ovs_scan("123", "%o%o", &i, &i2)); | |
718 | ovs_assert(ovs_scan("+123", "%o", &i)); | |
719 | ovs_assert(i == 0123); | |
720 | ovs_assert(ovs_scan("-123", "%o", &i)); | |
721 | ovs_assert(i == -0123); | |
722 | ovs_assert(ovs_scan("0123", "%o", &i)); | |
723 | ovs_assert(i == 0123); | |
724 | ovs_assert(ovs_scan(" 123", "%o", &i)); | |
725 | ovs_assert(i == 0123); | |
726 | ovs_assert(ovs_scan("0x123", "%o", &i)); | |
727 | ovs_assert(i == 0); | |
728 | ovs_assert(ovs_scan("123", "%2o %o", &i, &i2)); | |
729 | ovs_assert(i == 012); | |
730 | ovs_assert(i2 == 3); | |
731 | ovs_assert(ovs_scan("+123", "%2o %o", &i, &i2)); | |
732 | ovs_assert(i == 1); | |
733 | ovs_assert(i2 == 023); | |
734 | ovs_assert(ovs_scan("-123", "%2o %o", &i, &i2)); | |
735 | ovs_assert(i == -1); | |
736 | ovs_assert(i2 == 023); | |
737 | ovs_assert(ovs_scan("0123", "%2o %o", &i, &i2)); | |
738 | ovs_assert(i == 1); | |
739 | ovs_assert(i2 == 023); | |
740 | ovs_assert(ovs_scan("123", "%*2o %o", &i)); | |
741 | ovs_assert(i == 3); | |
742 | ovs_assert(ovs_scan("+123", "%2o %*o", &i)); | |
743 | ovs_assert(i == 1); | |
744 | ovs_assert(i2 == 023); | |
745 | ovs_assert(ovs_scan("-123", "%*2o %*o")); | |
746 | ||
747 | ovs_assert(ovs_scan("123", "%x", &i)); | |
748 | ovs_assert(i == 0x123); | |
749 | ovs_assert(ovs_scan("0", "%x", &i)); | |
750 | ovs_assert(i == 0); | |
751 | ovs_assert(!ovs_scan("123", "%x%x", &i, &i2)); | |
752 | ovs_assert(ovs_scan("+123", "%x", &i)); | |
753 | ovs_assert(i == 0x123); | |
754 | ovs_assert(ovs_scan("-123", "%x", &i)); | |
755 | ovs_assert(i == -0x123); | |
756 | ovs_assert(ovs_scan("0123", "%x", &i)); | |
757 | ovs_assert(i == 0x123); | |
758 | ovs_assert(ovs_scan(" 123", "%x", &i)); | |
759 | ovs_assert(i == 0x123); | |
760 | ovs_assert(ovs_scan("0x123", "%x", &i)); | |
761 | ovs_assert(i == 0x123); | |
762 | ovs_assert(ovs_scan("123", "%2x %x", &i, &i2)); | |
763 | ovs_assert(i == 0x12); | |
764 | ovs_assert(i2 == 3); | |
765 | ovs_assert(ovs_scan("+123", "%2x %x", &i, &i2)); | |
766 | ovs_assert(i == 1); | |
767 | ovs_assert(i2 == 0x23); | |
768 | ovs_assert(ovs_scan("-123", "%2x %x", &i, &i2)); | |
769 | ovs_assert(i == -1); | |
770 | ovs_assert(i2 == 0x23); | |
771 | ovs_assert(ovs_scan("0123", "%2x %x", &i, &i2)); | |
772 | ovs_assert(i == 1); | |
773 | ovs_assert(i2 == 0x23); | |
774 | ovs_assert(ovs_scan("123", "%*2x %x", &i)); | |
775 | ovs_assert(i == 3); | |
776 | ovs_assert(ovs_scan("+123", "%2x %*x", &i)); | |
777 | ovs_assert(i == 1); | |
778 | ovs_assert(i2 == 0x23); | |
779 | ovs_assert(ovs_scan("-123", "%*2x %*x")); | |
780 | ||
781 | ovs_assert(ovs_scan("123", "%hd", &s)); | |
782 | ovs_assert(s == 123); | |
783 | ovs_assert(!ovs_scan("123", "%hd%hd", &s, &s2)); | |
784 | ovs_assert(ovs_scan("+123", "%hd", &s)); | |
785 | ovs_assert(s == 123); | |
786 | ovs_assert(ovs_scan("-123", "%hd", &s)); | |
787 | ovs_assert(s == -123); | |
788 | ovs_assert(ovs_scan("0123", "%hd", &s)); | |
789 | ovs_assert(s == 123); | |
790 | ovs_assert(ovs_scan(" 123", "%hd", &s)); | |
791 | ovs_assert(s == 123); | |
792 | ovs_assert(ovs_scan("0x123", "%hd", &s)); | |
793 | ovs_assert(s == 0); | |
794 | ovs_assert(ovs_scan("123", "%2hd %hd", &s, &s2)); | |
795 | ovs_assert(s == 12); | |
796 | ovs_assert(s2 == 3); | |
797 | ovs_assert(ovs_scan("+123", "%2hd %hd", &s, &s2)); | |
798 | ovs_assert(s == 1); | |
799 | ovs_assert(s2 == 23); | |
800 | ovs_assert(ovs_scan("-123", "%2hd %hd", &s, &s2)); | |
801 | ovs_assert(s == -1); | |
802 | ovs_assert(s2 == 23); | |
803 | ovs_assert(ovs_scan("0123", "%2hd %hd", &s, &s2)); | |
804 | ovs_assert(s == 1); | |
805 | ovs_assert(s2 == 23); | |
806 | ||
807 | ovs_assert(ovs_scan("123", "%hhd", &c)); | |
808 | ovs_assert(c == 123); | |
809 | ovs_assert(ovs_scan("0", "%hhd", &c)); | |
810 | ovs_assert(c == 0); | |
811 | ovs_assert(!ovs_scan("123", "%hhd%hhd", &c, &c2)); | |
812 | ovs_assert(ovs_scan("+123", "%hhd", &c)); | |
813 | ovs_assert(c == 123); | |
814 | ovs_assert(ovs_scan("-123", "%hhd", &c)); | |
815 | ovs_assert(c == -123); | |
816 | ovs_assert(ovs_scan("0123", "%hhd", &c)); | |
817 | ovs_assert(c == 123); | |
818 | ovs_assert(ovs_scan(" 123", "%hhd", &c)); | |
819 | ovs_assert(c == 123); | |
820 | ovs_assert(ovs_scan("0x123", "%hhd", &c)); | |
821 | ovs_assert(c == 0); | |
822 | ovs_assert(ovs_scan("123", "%2hhd %hhd", &c, &c2)); | |
823 | ovs_assert(c == 12); | |
824 | ovs_assert(c2 == 3); | |
825 | ovs_assert(ovs_scan("+123", "%2hhd %hhd", &c, &c2)); | |
826 | ovs_assert(c == 1); | |
827 | ovs_assert(c2 == 23); | |
828 | ovs_assert(ovs_scan("-123", "%2hhd %hhd", &c, &c2)); | |
829 | ovs_assert(c == -1); | |
830 | ovs_assert(c2 == 23); | |
831 | ovs_assert(ovs_scan("0123", "%2hhd %hhd", &c, &c2)); | |
832 | ovs_assert(c == 1); | |
833 | ovs_assert(c2 == 23); | |
834 | ||
835 | ovs_assert(ovs_scan("123", "%ld", &l)); | |
836 | ovs_assert(l == 123); | |
837 | ovs_assert(ovs_scan("0", "%ld", &l)); | |
838 | ovs_assert(l == 0); | |
839 | ovs_assert(!ovs_scan("123", "%ld%ld", &l, &l2)); | |
840 | ovs_assert(ovs_scan("+123", "%ld", &l)); | |
841 | ovs_assert(l == 123); | |
842 | ovs_assert(ovs_scan("-123", "%ld", &l)); | |
843 | ovs_assert(l == -123); | |
844 | ovs_assert(ovs_scan("0123", "%ld", &l)); | |
845 | ovs_assert(l == 123); | |
846 | ovs_assert(ovs_scan(" 123", "%ld", &l)); | |
847 | ovs_assert(l == 123); | |
848 | ovs_assert(ovs_scan("0x123", "%ld", &l)); | |
849 | ovs_assert(l == 0); | |
850 | ovs_assert(ovs_scan("123", "%2ld %ld", &l, &l2)); | |
851 | ovs_assert(l == 12); | |
852 | ovs_assert(l2 == 3); | |
853 | ovs_assert(ovs_scan("+123", "%2ld %ld", &l, &l2)); | |
854 | ovs_assert(l == 1); | |
855 | ovs_assert(l2 == 23); | |
856 | ovs_assert(ovs_scan("-123", "%2ld %ld", &l, &l2)); | |
857 | ovs_assert(l == -1); | |
858 | ovs_assert(l2 == 23); | |
859 | ovs_assert(ovs_scan("0123", "%2ld %ld", &l, &l2)); | |
860 | ovs_assert(l == 1); | |
861 | ovs_assert(l2 == 23); | |
862 | ||
863 | ovs_assert(ovs_scan("123", "%lld", &ll)); | |
864 | ovs_assert(ll == 123); | |
865 | ovs_assert(ovs_scan("0", "%lld", &ll)); | |
866 | ovs_assert(ll == 0); | |
867 | ovs_assert(!ovs_scan("123", "%lld%lld", &ll, &ll2)); | |
868 | ovs_assert(ovs_scan("+123", "%lld", &ll)); | |
869 | ovs_assert(ll == 123); | |
870 | ovs_assert(ovs_scan("-123", "%lld", &ll)); | |
871 | ovs_assert(ll == -123); | |
872 | ovs_assert(ovs_scan("0123", "%lld", &ll)); | |
873 | ovs_assert(ll == 123); | |
874 | ovs_assert(ovs_scan(" 123", "%lld", &ll)); | |
875 | ovs_assert(ll == 123); | |
876 | ovs_assert(ovs_scan("0x123", "%lld", &ll)); | |
877 | ovs_assert(ll == 0); | |
878 | ovs_assert(ovs_scan("123", "%2lld %lld", &ll, &ll2)); | |
879 | ovs_assert(ll == 12); | |
880 | ovs_assert(ll2 == 3); | |
881 | ovs_assert(ovs_scan("+123", "%2lld %lld", &ll, &ll2)); | |
882 | ovs_assert(ll == 1); | |
883 | ovs_assert(ll2 == 23); | |
884 | ovs_assert(ovs_scan("-123", "%2lld %lld", &ll, &ll2)); | |
885 | ovs_assert(ll == -1); | |
886 | ovs_assert(ll2 == 23); | |
887 | ovs_assert(ovs_scan("0123", "%2lld %lld", &ll, &ll2)); | |
888 | ovs_assert(ll == 1); | |
889 | ovs_assert(ll2 == 23); | |
890 | ||
891 | ovs_assert(ovs_scan("123", "%jd", &im)); | |
892 | ovs_assert(im == 123); | |
893 | ovs_assert(ovs_scan("0", "%jd", &im)); | |
894 | ovs_assert(im == 0); | |
895 | ovs_assert(!ovs_scan("123", "%jd%jd", &im, &im2)); | |
896 | ovs_assert(ovs_scan("+123", "%jd", &im)); | |
897 | ovs_assert(im == 123); | |
898 | ovs_assert(ovs_scan("-123", "%jd", &im)); | |
899 | ovs_assert(im == -123); | |
900 | ovs_assert(ovs_scan("0123", "%jd", &im)); | |
901 | ovs_assert(im == 123); | |
902 | ovs_assert(ovs_scan(" 123", "%jd", &im)); | |
903 | ovs_assert(im == 123); | |
904 | ovs_assert(ovs_scan("0x123", "%jd", &im)); | |
905 | ovs_assert(im == 0); | |
906 | ovs_assert(ovs_scan("123", "%2jd %jd", &im, &im2)); | |
907 | ovs_assert(im == 12); | |
908 | ovs_assert(im2 == 3); | |
909 | ovs_assert(ovs_scan("+123", "%2jd %jd", &im, &im2)); | |
910 | ovs_assert(im == 1); | |
911 | ovs_assert(im2 == 23); | |
912 | ovs_assert(ovs_scan("-123", "%2jd %jd", &im, &im2)); | |
913 | ovs_assert(im == -1); | |
914 | ovs_assert(im2 == 23); | |
915 | ovs_assert(ovs_scan("0123", "%2jd %jd", &im, &im2)); | |
916 | ovs_assert(im == 1); | |
917 | ovs_assert(im2 == 23); | |
918 | ||
919 | ovs_assert(ovs_scan("123", "%td", &pd)); | |
920 | ovs_assert(pd == 123); | |
921 | ovs_assert(ovs_scan("0", "%td", &pd)); | |
922 | ovs_assert(pd == 0); | |
923 | ovs_assert(!ovs_scan("123", "%td%td", &pd, &pd2)); | |
924 | ovs_assert(ovs_scan("+123", "%td", &pd)); | |
925 | ovs_assert(pd == 123); | |
926 | ovs_assert(ovs_scan("-123", "%td", &pd)); | |
927 | ovs_assert(pd == -123); | |
928 | ovs_assert(ovs_scan("0123", "%td", &pd)); | |
929 | ovs_assert(pd == 123); | |
930 | ovs_assert(ovs_scan(" 123", "%td", &pd)); | |
931 | ovs_assert(pd == 123); | |
932 | ovs_assert(ovs_scan("0x123", "%td", &pd)); | |
933 | ovs_assert(pd == 0); | |
934 | ovs_assert(ovs_scan("123", "%2td %td", &pd, &pd2)); | |
935 | ovs_assert(pd == 12); | |
936 | ovs_assert(pd2 == 3); | |
937 | ovs_assert(ovs_scan("+123", "%2td %td", &pd, &pd2)); | |
938 | ovs_assert(pd == 1); | |
939 | ovs_assert(pd2 == 23); | |
940 | ovs_assert(ovs_scan("-123", "%2td %td", &pd, &pd2)); | |
941 | ovs_assert(pd == -1); | |
942 | ovs_assert(pd2 == 23); | |
943 | ovs_assert(ovs_scan("0123", "%2td %td", &pd, &pd2)); | |
944 | ovs_assert(pd == 1); | |
945 | ovs_assert(pd2 == 23); | |
946 | ||
947 | ovs_assert(ovs_scan("123", "%zd", &sz)); | |
948 | ovs_assert(sz == 123); | |
949 | ovs_assert(ovs_scan("0", "%zd", &sz)); | |
950 | ovs_assert(sz == 0); | |
951 | ovs_assert(!ovs_scan("123", "%zd%zd", &sz, &sz2)); | |
952 | ovs_assert(ovs_scan("+123", "%zd", &sz)); | |
953 | ovs_assert(sz == 123); | |
954 | ovs_assert(ovs_scan("-123", "%zd", &sz)); | |
955 | ovs_assert(sz == -123); | |
956 | ovs_assert(ovs_scan("0123", "%zd", &sz)); | |
957 | ovs_assert(sz == 123); | |
958 | ovs_assert(ovs_scan(" 123", "%zd", &sz)); | |
959 | ovs_assert(sz == 123); | |
960 | ovs_assert(ovs_scan("0x123", "%zd", &sz)); | |
961 | ovs_assert(sz == 0); | |
962 | ovs_assert(ovs_scan("123", "%2zd %zd", &sz, &sz2)); | |
963 | ovs_assert(sz == 12); | |
964 | ovs_assert(sz2 == 3); | |
965 | ovs_assert(ovs_scan("+123", "%2zd %zd", &sz, &sz2)); | |
966 | ovs_assert(sz == 1); | |
967 | ovs_assert(sz2 == 23); | |
968 | ovs_assert(ovs_scan("-123", "%2zd %zd", &sz, &sz2)); | |
969 | ovs_assert(sz == -1); | |
970 | ovs_assert(sz2 == 23); | |
971 | ovs_assert(ovs_scan("0123", "%2zd %zd", &sz, &sz2)); | |
972 | ovs_assert(sz == 1); | |
973 | ovs_assert(sz2 == 23); | |
974 | ||
975 | ovs_assert(ovs_scan("0.25", "%f", &f)); | |
976 | ovs_assert(f == 0.25); | |
977 | ovs_assert(ovs_scan("1.0", "%f", &f)); | |
978 | ovs_assert(f == 1.0); | |
979 | ovs_assert(ovs_scan("-5", "%f", &f)); | |
980 | ovs_assert(f == -5.0); | |
981 | ovs_assert(ovs_scan("+6", "%f", &f)); | |
982 | ovs_assert(f == 6.0); | |
983 | ovs_assert(ovs_scan("-1e5", "%f", &f)); | |
984 | ovs_assert(f == -1e5); | |
985 | ovs_assert(ovs_scan("-.25", "%f", &f)); | |
986 | ovs_assert(f == -.25); | |
987 | ovs_assert(ovs_scan("+123.e1", "%f", &f)); | |
988 | ovs_assert(f == 1230.0); | |
989 | ovs_assert(ovs_scan("25e-2", "%f", &f)); | |
990 | ovs_assert(f == 0.25); | |
991 | ovs_assert(ovs_scan("0.25", "%1f %f", &f, &f2)); | |
992 | ovs_assert(f == 0); | |
993 | ovs_assert(f2 == 0.25); | |
994 | ovs_assert(ovs_scan("1.0", "%2f %f", &f, &f2)); | |
995 | ovs_assert(f == 1.0); | |
996 | ovs_assert(f2 == 0.0); | |
997 | ovs_assert(!ovs_scan("-5", "%1f", &f)); | |
998 | ovs_assert(!ovs_scan("+6", "%1f", &f)); | |
999 | ovs_assert(!ovs_scan("-1e5", "%2f %*f", &f)); | |
1000 | ovs_assert(f == -1); | |
1001 | ovs_assert(!ovs_scan("-.25", "%2f", &f)); | |
1002 | ovs_assert(!ovs_scan("+123.e1", "%6f", &f)); | |
1003 | ovs_assert(!ovs_scan("25e-2", "%4f", &f)); | |
1004 | ||
1005 | ovs_assert(ovs_scan("0.25", "%lf", &d)); | |
1006 | ovs_assert(d == 0.25); | |
1007 | ovs_assert(ovs_scan("1.0", "%lf", &d)); | |
1008 | ovs_assert(d == 1.0); | |
1009 | ovs_assert(ovs_scan("-5", "%lf", &d)); | |
1010 | ovs_assert(d == -5.0); | |
1011 | ovs_assert(ovs_scan("+6", "%lf", &d)); | |
1012 | ovs_assert(d == 6.0); | |
1013 | ovs_assert(ovs_scan("-1e5", "%lf", &d)); | |
1014 | ovs_assert(d == -1e5); | |
1015 | ovs_assert(ovs_scan("-.25", "%lf", &d)); | |
1016 | ovs_assert(d == -.25); | |
1017 | ovs_assert(ovs_scan("+123.e1", "%lf", &d)); | |
1018 | ovs_assert(d == 1230.0); | |
1019 | ovs_assert(ovs_scan("25e-2", "%lf", &d)); | |
1020 | ovs_assert(d == 0.25); | |
1021 | ovs_assert(ovs_scan("0.25", "%1lf %lf", &d, &d2)); | |
1022 | ovs_assert(d == 0); | |
1023 | ovs_assert(d2 == 0.25); | |
1024 | ovs_assert(ovs_scan("1.0", "%2lf %lf", &d, &d2)); | |
1025 | ovs_assert(d == 1.0); | |
1026 | ovs_assert(d2 == 0.0); | |
1027 | ovs_assert(!ovs_scan("-5", "%1lf", &d)); | |
1028 | ovs_assert(!ovs_scan("+6", "%1lf", &d)); | |
1029 | ovs_assert(!ovs_scan("-1e5", "%2lf %*f", &d)); | |
1030 | ovs_assert(d == -1); | |
1031 | ovs_assert(!ovs_scan("-.25", "%2lf", &d)); | |
1032 | ovs_assert(!ovs_scan("+123.e1", "%6lf", &d)); | |
1033 | ovs_assert(!ovs_scan("25e-2", "%4lf", &d)); | |
1034 | ||
1035 | ovs_assert(ovs_scan("0.25", "%Lf", &ld)); | |
1036 | ovs_assert(ld == 0.25); | |
1037 | ovs_assert(ovs_scan("1.0", "%Lf", &ld)); | |
1038 | ovs_assert(ld == 1.0); | |
1039 | ovs_assert(ovs_scan("-5", "%Lf", &ld)); | |
1040 | ovs_assert(ld == -5.0); | |
1041 | ovs_assert(ovs_scan("+6", "%Lf", &ld)); | |
1042 | ovs_assert(ld == 6.0); | |
1043 | ovs_assert(ovs_scan("-1e5", "%Lf", &ld)); | |
1044 | ovs_assert(ld == -1e5); | |
1045 | ovs_assert(ovs_scan("-.25", "%Lf", &ld)); | |
1046 | ovs_assert(ld == -.25); | |
1047 | ovs_assert(ovs_scan("+123.e1", "%Lf", &ld)); | |
1048 | ovs_assert(ld == 1230.0); | |
1049 | ovs_assert(ovs_scan("25e-2", "%Lf", &ld)); | |
1050 | ovs_assert(ld == 0.25); | |
1051 | ovs_assert(ovs_scan("0.25", "%1Lf %Lf", &ld, &ld2)); | |
1052 | ovs_assert(ld == 0); | |
1053 | ovs_assert(ld2 == 0.25); | |
1054 | ovs_assert(ovs_scan("1.0", "%2Lf %Lf", &ld, &ld2)); | |
1055 | ovs_assert(ld == 1.0); | |
1056 | ovs_assert(ld2 == 0.0); | |
1057 | ovs_assert(!ovs_scan("-5", "%1Lf", &ld)); | |
1058 | ovs_assert(!ovs_scan("+6", "%1Lf", &ld)); | |
1059 | ovs_assert(!ovs_scan("-1e5", "%2Lf %*f", &ld)); | |
1060 | ovs_assert(ld == -1); | |
1061 | ovs_assert(!ovs_scan("-.25", "%2Lf", &ld)); | |
1062 | ovs_assert(!ovs_scan("+123.e1", "%6Lf", &ld)); | |
1063 | ovs_assert(!ovs_scan("25e-2", "%4Lf", &ld)); | |
1064 | ||
1065 | ovs_assert(ovs_scan(" Hello,\tworld ", "%*s%n%*s%n", &n, &n2)); | |
1066 | ovs_assert(n == 7); | |
1067 | ovs_assert(n2 == 13); | |
1068 | ovs_assert(!ovs_scan(" Hello,\tworld ", "%*s%*s%*s")); | |
1069 | ovs_assert(ovs_scan(" Hello,\tworld ", "%6s%n%5s%n", str, &n, str2, &n2)); | |
1070 | ovs_assert(!strcmp(str, "Hello,")); | |
1071 | ovs_assert(n == 7); | |
1072 | ovs_assert(!strcmp(str2, "world")); | |
1073 | ovs_assert(n2 == 13); | |
1074 | ovs_assert(ovs_scan(" Hello,\tworld ", "%5s%5s%5s", str, str2, str3)); | |
1075 | ovs_assert(!strcmp(str, "Hello")); | |
1076 | ovs_assert(!strcmp(str2, ",")); | |
1077 | ovs_assert(!strcmp(str3, "world")); | |
1078 | ovs_assert(!ovs_scan(" ", "%*s")); | |
1079 | ||
1080 | ovs_assert(ovs_scan(" Hello,\tworld ", "%*c%n%*c%n%c%n", | |
1081 | &n, &n2, &c, &n3)); | |
1082 | ovs_assert(n == 1); | |
1083 | ovs_assert(n2 == 2); | |
1084 | ovs_assert(c == 'e'); | |
1085 | ovs_assert(n3 == 3); | |
1086 | ovs_assert(ovs_scan(" Hello,\tworld ", "%*5c%5c", str)); | |
1087 | ovs_assert(!memcmp(str, "o,\two", 5)); | |
1088 | ovs_assert(!ovs_scan(" Hello,\tworld ", "%*15c")); | |
1089 | ||
1090 | ovs_assert(ovs_scan("0x1234xyzzy", "%9[x0-9a-fA-F]%n", str, &n)); | |
1091 | ovs_assert(!strcmp(str, "0x1234x")); | |
1092 | ovs_assert(n == 7); | |
1093 | ovs_assert(ovs_scan("foo:bar=baz", "%5[^:=]%n:%5[^:=]%n=%5[^:=]%n", | |
1094 | str, &n, str2, &n2, str3, &n3)); | |
1095 | ovs_assert(!strcmp(str, "foo")); | |
1096 | ovs_assert(n == 3); | |
1097 | ovs_assert(!strcmp(str2, "bar")); | |
1098 | ovs_assert(n2 == 7); | |
1099 | ovs_assert(!strcmp(str3, "baz")); | |
1100 | ovs_assert(n3 == 11); | |
1101 | ovs_assert(!ovs_scan(" ", "%*[0-9]")); | |
1102 | ovs_assert(ovs_scan("0x123a]4xyzzy-", "%[]x0-9a-fA-F]", str)); | |
1103 | ovs_assert(!strcmp(str, "0x123a]4x")); | |
1104 | ovs_assert(ovs_scan("abc]xyz","%[^]xyz]", str)); | |
1105 | ovs_assert(!strcmp(str, "abc")); | |
1106 | ovs_assert(!ovs_scan("0x123a]4xyzzy-", "%[x0-9]a-fA-F]", str)); | |
1107 | ovs_assert(ovs_scan("0x12-3]xyz", "%[x0-9a-f-]", str)); | |
1108 | ovs_assert(!strcmp(str, "0x12-3")); | |
1109 | ovs_assert(ovs_scan("0x12-3]xyz", "%[^a-f-]", str)); | |
1110 | ovs_assert(!strcmp(str, "0x12")); | |
1111 | ovs_assert(sscanf("0x12-3]xyz", "%[^-a-f]", str)); | |
1112 | ovs_assert(!strcmp(str, "0x12")); | |
1113 | } | |
1114 | ||
1115 | static void | |
1116 | test_snprintf(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
1117 | { | |
1118 | char s[16]; | |
1119 | ||
1120 | #if __GNUC__ >= 7 | |
1121 | /* GCC 7+ warns about the following calls that truncate a string using | |
1122 | * snprintf(). We're testing that truncation works properly, so | |
1123 | * temporarily disable the warning. */ | |
1124 | #pragma GCC diagnostic push | |
1125 | #pragma GCC diagnostic ignored "-Wformat-truncation" | |
1126 | #endif | |
1127 | ovs_assert(snprintf(s, 4, "abcde") == 5); | |
1128 | ovs_assert(!strcmp(s, "abc")); | |
1129 | ||
1130 | ovs_assert(snprintf(s, 5, "abcde") == 5); | |
1131 | ovs_assert(!strcmp(s, "abcd")); | |
1132 | #if __GNUC__ >= 7 | |
1133 | #pragma GCC diagnostic pop | |
1134 | #endif | |
1135 | ||
1136 | ovs_assert(snprintf(s, 6, "abcde") == 5); | |
1137 | ovs_assert(!strcmp(s, "abcde")); | |
1138 | ||
1139 | ovs_assert(snprintf(NULL, 0, "abcde") == 5); | |
1140 | } | |
1141 | ||
1142 | static void | |
1143 | check_sat(long long int x, long long int y, const char *op, | |
1144 | long long int r_a, long long int r_b) | |
1145 | { | |
1146 | if (r_a != r_b) { | |
1147 | fprintf(stderr, "%lld %s %lld saturates differently: %lld vs %lld\n", | |
1148 | x, op, y, r_a, r_b); | |
1149 | abort(); | |
1150 | } | |
1151 | } | |
1152 | ||
1153 | static void | |
1154 | test_sat_math(struct ovs_cmdl_context *ctx OVS_UNUSED) | |
1155 | { | |
1156 | long long int values[] = { | |
1157 | LLONG_MIN, LLONG_MIN + 1, LLONG_MIN + 2, LLONG_MIN + 3, | |
1158 | LLONG_MIN + 4, LLONG_MIN + 5, LLONG_MIN + 6, LLONG_MIN + 7, | |
1159 | LLONG_MIN / 2, LLONG_MIN / 3, LLONG_MIN / 4, LLONG_MIN / 5, | |
1160 | -1000, -50, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, | |
1161 | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 50, 1000, | |
1162 | LLONG_MAX / 5, LLONG_MAX / 4, LLONG_MAX / 3, LLONG_MAX / 2, | |
1163 | LLONG_MAX - 7, LLONG_MAX - 6, LLONG_MAX - 5, LLONG_MAX - 4, | |
1164 | LLONG_MAX - 3, LLONG_MAX - 2, LLONG_MAX - 1, LLONG_MAX, | |
1165 | }; | |
1166 | ||
1167 | /* Compare the behavior of our local implementation of these functions | |
1168 | * against the compiler implementation or its fallback. (If the fallback | |
1169 | * is in use then this is comparing the fallback to itself, so this test is | |
1170 | * only really useful if the compiler has an implementation.) */ | |
1171 | for (long long int *x = values; x < values + ARRAY_SIZE(values); x++) { | |
1172 | for (long long int *y = values; y < values + ARRAY_SIZE(values); y++) { | |
1173 | check_sat(*x, *y, "+", llsat_add(*x, *y), llsat_add__(*x, *y)); | |
1174 | check_sat(*x, *y, "-", llsat_sub(*x, *y), llsat_sub__(*x, *y)); | |
1175 | check_sat(*x, *y, "*", llsat_mul(*x, *y), llsat_mul__(*x, *y)); | |
1176 | } | |
1177 | } | |
1178 | } | |
1179 | ||
1180 | #ifndef _WIN32 | |
1181 | static void | |
1182 | test_file_name(struct ovs_cmdl_context *ctx) | |
1183 | { | |
1184 | int i; | |
1185 | ||
1186 | for (i = 1; i < ctx->argc; i++) { | |
1187 | char *dir, *base; | |
1188 | ||
1189 | dir = dir_name(ctx->argv[i]); | |
1190 | puts(dir); | |
1191 | free(dir); | |
1192 | ||
1193 | base = base_name(ctx->argv[i]); | |
1194 | puts(base); | |
1195 | free(base); | |
1196 | } | |
1197 | } | |
1198 | #endif /* _WIN32 */ | |
1199 | \f | |
1200 | static const struct ovs_cmdl_command commands[] = { | |
1201 | {"ctz", NULL, 0, 0, test_ctz, OVS_RO}, | |
1202 | {"clz", NULL, 0, 0, test_clz, OVS_RO}, | |
1203 | {"round_up_pow2", NULL, 0, 0, test_round_up_pow2, OVS_RO}, | |
1204 | {"round_down_pow2", NULL, 0, 0, test_round_down_pow2, OVS_RO}, | |
1205 | {"count_1bits", NULL, 0, 0, test_count_1bits, OVS_RO}, | |
1206 | {"log_2_floor", NULL, 0, 0, test_log_2_floor, OVS_RO}, | |
1207 | {"bitwise_copy", NULL, 0, 0, test_bitwise_copy, OVS_RO}, | |
1208 | {"bitwise_zero", NULL, 0, 0, test_bitwise_zero, OVS_RO}, | |
1209 | {"bitwise_one", NULL, 0, 0, test_bitwise_one, OVS_RO}, | |
1210 | {"bitwise_is_all_zeros", NULL, 0, 0, test_bitwise_is_all_zeros, OVS_RO}, | |
1211 | {"bitwise_rscan", NULL, 0, 0, test_bitwise_rscan, OVS_RO}, | |
1212 | {"follow-symlinks", NULL, 1, INT_MAX, test_follow_symlinks, OVS_RO}, | |
1213 | {"assert", NULL, 0, 0, test_assert, OVS_RO}, | |
1214 | {"ovs_scan", NULL, 0, 0, test_ovs_scan, OVS_RO}, | |
1215 | {"snprintf", NULL, 0, 0, test_snprintf, OVS_RO}, | |
1216 | {"sat_math", NULL, 0, 0, test_sat_math, OVS_RO}, | |
1217 | #ifndef _WIN32 | |
1218 | {"file_name", NULL, 1, INT_MAX, test_file_name, OVS_RO}, | |
1219 | #endif | |
1220 | {NULL, NULL, 0, 0, NULL, OVS_RO}, | |
1221 | }; | |
1222 | ||
1223 | static void | |
1224 | parse_options(int argc, char *argv[]) | |
1225 | { | |
1226 | enum { | |
1227 | VLOG_OPTION_ENUMS | |
1228 | }; | |
1229 | static const struct option long_options[] = { | |
1230 | VLOG_LONG_OPTIONS, | |
1231 | {NULL, 0, NULL, 0}, | |
1232 | }; | |
1233 | char *short_options = ovs_cmdl_long_options_to_short_options(long_options); | |
1234 | ||
1235 | for (;;) { | |
1236 | int c = getopt_long(argc, argv, short_options, long_options, NULL); | |
1237 | if (c == -1) { | |
1238 | break; | |
1239 | } | |
1240 | ||
1241 | switch (c) { | |
1242 | VLOG_OPTION_HANDLERS | |
1243 | ||
1244 | case '?': | |
1245 | exit(EXIT_FAILURE); | |
1246 | ||
1247 | default: | |
1248 | abort(); | |
1249 | } | |
1250 | } | |
1251 | free(short_options); | |
1252 | } | |
1253 | ||
1254 | static void | |
1255 | test_util_main(int argc, char *argv[]) | |
1256 | { | |
1257 | struct ovs_cmdl_context ctx = { .argc = 0, }; | |
1258 | set_program_name(argv[0]); | |
1259 | parse_options(argc, argv); | |
1260 | /* On Windows, stderr is fully buffered if connected to a pipe. | |
1261 | * Make it _IONBF so that an abort does not miss log contents. | |
1262 | * POSIX doesn't define the circumstances in which stderr is | |
1263 | * fully buffered either. */ | |
1264 | setvbuf(stderr, NULL, _IONBF, 0); | |
1265 | ctx.argc = argc - optind; | |
1266 | ctx.argv = argv + optind; | |
1267 | ovs_cmdl_run_command(&ctx, commands); | |
1268 | } | |
1269 | ||
1270 | OVSTEST_REGISTER("test-util", test_util_main); |