]> git.proxmox.com Git - ovs.git/blame - tests/test-util.c
raft: Fix the problem of stuck in candidate role forever.
[ovs.git] / tests / test-util.c
CommitLineData
711e0157 1/*
74142432 2 * Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2019 Nicira, Inc.
711e0157
BP
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>
3f636c7e
JR
18#undef NDEBUG
19#include "util.h"
20#include <assert.h>
4749f73d 21#include <getopt.h>
711e0157 22#include <inttypes.h>
aad29cd1 23#include <limits.h>
711e0157
BP
24#include <stdio.h>
25#include <stdlib.h>
ddc4f8e2 26#include "byte-order.h"
8c2296a6 27#include "command-line.h"
3f636c7e 28#include "ovstest.h"
711e0157 29#include "random.h"
74142432 30#include "sat-math.h"
e6211adc 31#include "openvswitch/vlog.h"
a656cb77 32
711e0157 33static void
aad29cd1 34check_log_2_floor(uint32_t x, int n)
711e0157
BP
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
8c2296a6 43static void
1636c761 44test_log_2_floor(struct ovs_cmdl_context *ctx OVS_UNUSED)
8c2296a6
BP
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
aad29cd1 62static void
d578065e 63check_ctz32(uint32_t x, int n)
aad29cd1 64{
d578065e
JR
65 if (ctz32(x) != n) {
66 fprintf(stderr, "ctz32(%"PRIu32") is %d but should be %d\n",
67 x, ctz32(x), n);
aad29cd1
BP
68 abort();
69 }
70}
71
cc4c738e
JR
72static void
73check_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
8c2296a6 82static void
1636c761 83test_ctz(struct ovs_cmdl_context *ctx OVS_UNUSED)
8c2296a6
BP
84{
85 int n;
86
87 for (n = 0; n < 32; n++) {
88 /* Check minimum x such that f(x) == n. */
d578065e 89 check_ctz32(1 << n, n);
8c2296a6
BP
90
91 /* Check maximum x such that f(x) == n. */
d578065e 92 check_ctz32(UINT32_MAX << n, n);
8c2296a6
BP
93
94 /* Check a random value in the middle. */
d578065e 95 check_ctz32((random_uint32() | 1) << n, n);
8c2296a6
BP
96 }
97
cc4c738e
JR
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
8c2296a6 110 /* Check ctz(0). */
d578065e 111 check_ctz32(0, 32);
cc4c738e 112 check_ctz64(0, 64);
8c2296a6
BP
113}
114
8c947903
JR
115static void
116check_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
125static void
126check_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
135static void
1636c761 136test_clz(struct ovs_cmdl_context *ctx OVS_UNUSED)
8c947903
JR
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
e93ab553
BP
167/* Returns a random number in the range 'min'...'max' inclusive. */
168static uint32_t
169random_in_range(uint32_t min, uint32_t max)
170{
171 return min == max ? min : min + random_range(max - min + 1);
172}
173
174static void
175check_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
185static void
1636c761 186test_round_up_pow2(struct ovs_cmdl_context *ctx OVS_UNUSED)
e93ab553
BP
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
202static void
203check_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
213static void
1636c761 214test_round_down_pow2(struct ovs_cmdl_context *ctx OVS_UNUSED)
e93ab553
BP
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
a656cb77 230static void
cc4c738e 231shuffle(uint64_t *p, size_t n)
a656cb77
BP
232{
233 for (; n > 1; n--, p++) {
cc4c738e
JR
234 uint64_t *q = &p[random_range(n)];
235 uint64_t tmp = *p;
a656cb77
BP
236 *p = *q;
237 *q = tmp;
238 }
239}
240
241static void
fb9aefa3 242check_count_1bits(uint64_t x, int n)
a656cb77 243{
fb9aefa3
BP
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);
a656cb77
BP
247 abort();
248 }
249}
250
251static void
1636c761 252test_count_1bits(struct ovs_cmdl_context *ctx OVS_UNUSED)
a656cb77 253{
cc4c738e 254 uint64_t bits[64];
a656cb77
BP
255 int i;
256
257 for (i = 0; i < ARRAY_SIZE(bits); i++) {
cc4c738e 258 bits[i] = UINT64_C(1) << i;
a656cb77
BP
259 }
260
fb9aefa3 261 check_count_1bits(0, 0);
cc4c738e
JR
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];
fb9aefa3 270 check_count_1bits(x, j + 1);
cc4c738e
JR
271 }
272 assert(x == UINT64_MAX);
273
274 shuffle(bits, ARRAY_SIZE(bits));
275 for (j = 63; j >= 0; j--) {
276 x &= ~bits[j];
fb9aefa3 277 check_count_1bits(x, j);
cc4c738e
JR
278 }
279 assert(x == 0);
280 }
a656cb77
BP
281}
282
ddc4f8e2
BP
283/* Returns the sum of the squares of the first 'n' positive integers. */
284static unsigned int
285sum_of_squares(int n)
286{
287 return n * (n + 1) * (2 * n + 1) / 6;
288}
289
290static void
1636c761 291test_bitwise_copy(struct ovs_cmdl_context *ctx OVS_UNUSED)
ddc4f8e2
BP
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
6cc7ea5e 340static void
1636c761 341test_bitwise_zero(struct ovs_cmdl_context *ctx OVS_UNUSED)
6cc7ea5e
BP
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
c2dd4932 381static void
1636c761 382test_bitwise_one(struct ovs_cmdl_context *ctx OVS_UNUSED)
c2dd4932
BP
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) {
b8266395 396 expect = OVS_BE64_MAX;
c2dd4932
BP
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
79a010aa 422static void
1636c761 423test_bitwise_is_all_zeros(struct ovs_cmdl_context *ctx OVS_UNUSED)
79a010aa
BP
424{
425 int n_loops;
426
79a010aa
BP
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 {
b028db44 437 bit = htonll(UINT64_C(1) << (random_range(64)));
79a010aa
BP
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}
fee0c963 465
76adea87
HZ
466static int
467trivial_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
480static void
481test_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
fee0c963 566static void
1636c761 567test_follow_symlinks(struct ovs_cmdl_context *ctx)
fee0c963
BP
568{
569 int i;
570
1636c761
RB
571 for (i = 1; i < ctx->argc; i++) {
572 char *target = follow_symlinks(ctx->argv[i]);
fee0c963
BP
573 puts(target);
574 free(target);
575 }
576}
4749f73d
BP
577
578static void
1636c761 579test_assert(struct ovs_cmdl_context *ctx OVS_UNUSED)
4749f73d
BP
580{
581 ovs_assert(false);
582}
ed2232fc
BP
583
584static void
1636c761 585test_ovs_scan(struct ovs_cmdl_context *ctx OVS_UNUSED)
ed2232fc
BP
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
ed2232fc
BP
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}
cde1c287
BP
1114
1115static void
1636c761 1116test_snprintf(struct ovs_cmdl_context *ctx OVS_UNUSED)
cde1c287
BP
1117{
1118 char s[16];
1119
fa792e4f
BP
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
cde1c287
BP
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"));
fa792e4f
BP
1132#if __GNUC__ >= 7
1133#pragma GCC diagnostic pop
1134#endif
cde1c287
BP
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}
3c1150ce 1141
74142432
BP
1142static void
1143check_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
1153static void
1154test_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
3c1150ce
GS
1180#ifndef _WIN32
1181static void
1636c761 1182test_file_name(struct ovs_cmdl_context *ctx)
3c1150ce
GS
1183{
1184 int i;
1185
1636c761 1186 for (i = 1; i < ctx->argc; i++) {
3c1150ce
GS
1187 char *dir, *base;
1188
1636c761 1189 dir = dir_name(ctx->argv[i]);
3c1150ce
GS
1190 puts(dir);
1191 free(dir);
1192
1636c761 1193 base = base_name(ctx->argv[i]);
3c1150ce
GS
1194 puts(base);
1195 free(base);
1196 }
1197}
1198#endif /* _WIN32 */
8c2296a6 1199\f
5f383751 1200static const struct ovs_cmdl_command commands[] = {
1f4a7252
RM
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},
74142432 1216 {"sat_math", NULL, 0, 0, test_sat_math, OVS_RO},
3c1150ce 1217#ifndef _WIN32
1f4a7252 1218 {"file_name", NULL, 1, INT_MAX, test_file_name, OVS_RO},
3c1150ce 1219#endif
1f4a7252 1220 {NULL, NULL, 0, 0, NULL, OVS_RO},
8c2296a6 1221};
79a010aa 1222
4749f73d
BP
1223static void
1224parse_options(int argc, char *argv[])
1225{
1226 enum {
1227 VLOG_OPTION_ENUMS
1228 };
07fc4ed3 1229 static const struct option long_options[] = {
4749f73d
BP
1230 VLOG_LONG_OPTIONS,
1231 {NULL, 0, NULL, 0},
1232 };
5f383751 1233 char *short_options = ovs_cmdl_long_options_to_short_options(long_options);
4749f73d
BP
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
eadd1644
AZ
1254static void
1255test_util_main(int argc, char *argv[])
711e0157 1256{
1636c761 1257 struct ovs_cmdl_context ctx = { .argc = 0, };
8c2296a6 1258 set_program_name(argv[0]);
4749f73d 1259 parse_options(argc, argv);
784acd82
GS
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);
1636c761
RB
1265 ctx.argc = argc - optind;
1266 ctx.argv = argv + optind;
1267 ovs_cmdl_run_command(&ctx, commands);
711e0157 1268}
eadd1644
AZ
1269
1270OVSTEST_REGISTER("test-util", test_util_main);