Test bitstring macro evaluation.
authorbluhm <bluhm@openbsd.org>
Mon, 26 Aug 2024 12:15:40 +0000 (12:15 +0000)
committerbluhm <bluhm@openbsd.org>
Mon, 26 Aug 2024 12:15:40 +0000 (12:15 +0000)
For all bitstring macros, add a test with side effects in the
arguments.  Also fix compiler warnings and wrap long line.  In
main() replace exit(0) with return(0) to check stack canary.  Create
expected test files with make target create-good.

OK florian deraadt@

regress/include/bitstring/Makefile
regress/include/bitstring/bitstring_test.c
regress/include/bitstring/good/27
regress/include/bitstring/good/32
regress/include/bitstring/good/49
regress/include/bitstring/good/64
regress/include/bitstring/good/67
regress/include/bitstring/good/8

index 90f8baf..98fe9f4 100644 (file)
@@ -1,27 +1,20 @@
-#      $OpenBSD: Makefile,v 1.4 2002/09/02 20:01:43 avsm Exp $
+#      $OpenBSD: Makefile,v 1.5 2024/08/26 12:15:40 bluhm Exp $
 #      $NetBSD: Makefile,v 1.4 1995/04/20 22:37:50 cgd Exp $
 
-PROG=  ./bitstring_test
+PROG=  bitstring_test
 
-REGRESS_TARGETS=test-8 test-27 test-32 test-49 test-64 test-67
+REGRESS_TARGETS=
 
-test-8: ${PROG}
-       ${PROG} 8 | diff - ${.CURDIR}/good/8
+.for i in 8 27 32 49 64 67
 
-test-27: ${PROG}
-       ${PROG} 27 | diff - ${.CURDIR}/good/27
+REGRESS_TARGETS+=      run-test-$i
+run-test-$i: ${PROG}
+       ./${PROG} $i | diff - ${.CURDIR}/good/$i
 
-test-32: ${PROG}
-       ${PROG} 32 | diff - ${.CURDIR}/good/32
-
-test-49: ${PROG}
-       ${PROG} 49 | diff - ${.CURDIR}/good/49
-
-test-64: ${PROG}
-       ${PROG} 64 | diff - ${.CURDIR}/good/64
-
-test-67: ${PROG}
-       ${PROG} 67 | diff - ${.CURDIR}/good/67
+create-good: create-$i
+create-$i: ${PROG}
+       ./${PROG} $i >${.CURDIR}/good/$i
 
+.endfor
 
 .include <bsd.regress.mk>
index 836c021..d58ed0b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: bitstring_test.c,v 1.6 2024/08/23 17:19:16 florian Exp $   */
+/* $OpenBSD: bitstring_test.c,v 1.7 2024/08/26 12:15:40 bluhm Exp $     */
 /* $NetBSD: bitstring_test.c,v 1.4 1995/04/29 05:44:35 cgd Exp $        */
 
 /*
@@ -6,7 +6,7 @@
  * inspect the output, you should notice problems
  * choose the ATT or BSD flavor
  */
-/* #define ATT /*- */
+// #define ATT /*-*/
 #define BSD                    /*-*/
 
 /*
@@ -39,7 +39,7 @@ clearbits(bitstr_t *b, int n)
 static void
 printbits(bitstr_t *b, int n)
 {
-       register int    i;
+       register int    i, k;
        int             jc, js;
 
        bit_ffc(b, n, &jc);
@@ -54,7 +54,7 @@ printbits(bitstr_t *b, int n)
 int
 main(int argc, char *argv[])
 {
-       int             i;
+       int             i, j, k, *p;
        bitstr_t       *bs;
        bitstr_t        bit_decl(bss, DECL_TEST_LENGTH);
 
@@ -64,7 +64,8 @@ main(int argc, char *argv[])
                TEST_LENGTH = DECL_TEST_LENGTH;
 
        if (TEST_LENGTH < 4) {
-               fprintf(stderr, "TEST_LENGTH must be at least 4, but it is %d\n",
+               fprintf(stderr,
+                       "TEST_LENGTH must be at least 4, but it is %d\n",
                        TEST_LENGTH);
                exit(1);
        }
@@ -92,7 +93,7 @@ main(int argc, char *argv[])
        }
        (void) printf("be:   1   0 ");
        for (i = 0; i < TEST_LENGTH; i++)
-               (void) putchar(*("100" + (i % 3)));
+               (void) putchar("100"[i % 3]);
        (void) printf("\nis: ");
        printbits(bs, TEST_LENGTH);
 
@@ -102,7 +103,7 @@ main(int argc, char *argv[])
        }
        (void) printf("be:   0   3 ");
        for (i = 0; i < TEST_LENGTH; i++)
-               (void) putchar(*("000100" + (i % 6)));
+               (void) putchar("000100"[i % 6]);
        (void) printf("\nis: ");
        printbits(bs, TEST_LENGTH);
 
@@ -220,6 +221,38 @@ main(int argc, char *argv[])
                printbits(bs, TEST_LENGTH);
        }
 
+       (void) printf("\n");
+       (void) printf("macros should evaluate arguments only once\n");
+       i = j = 0;
+       _bit_byte(i++);
+       (void) printf("_bit_byte(%d) -> %d\n", j++, i);
+       _bit_mask(i++);
+       (void) printf("_bit_mask(%d) -> %d\n", j++, i);
+       bitstr_size(i++);
+       (void) printf("bitstr_size(%d) -> %d\n", j++, i);
+       free(bit_alloc(i++));
+       (void) printf("bit_alloc(%d) -> %d\n", j++, i);
+       { bitstr_t bit_decl(bd, i++); }
+       (void) printf("bit_alloc(%d) -> %d\n", j++, i);
+       bit_test(bs, i++);
+       (void) printf("bit_test(%d) -> %d\n", j++, i);
+       bit_set(bs, i++);
+       (void) printf("bit_set(%d) -> %d\n", j++, i);
+       bit_clear(bs, i++);
+       (void) printf("bit_clear(%d) -> %d\n", j++, i);
+       i %= TEST_LENGTH; j %= TEST_LENGTH;
+       bit_nclear(bs, i++, i++);
+       (void) printf("bit_nclear(%d, %d) -> %d\n", j, j + 1, i);
+       j += 2;
+       bit_nset(bs, i++, i++);
+       (void) printf("bit_nset(%d, %d) -> %d\n", j, j + 1, i);
+       j += 2;
+       p = &k;
+       bit_ffc(bs, i++, p++);
+       (void) printf("bit_ffc(%d, %ld) -> %d\n", j++, --p - &k, i);
+       bit_ffs(bs, i++, p++);
+       (void) printf("bit_ffs(%d, %ld) -> %d\n", j++, --p - &k, i);
+
        (void) free(bs);
-       (void) exit(0);
+       return (0);
 }
index f1479dd..f1acb16 100644 (file)
@@ -290,3 +290,17 @@ CHI square test
  24   0   2 001000000000000000000000100
  25   0   1 010000000000000000000000010
  26   1   0 100000000000000000000000001
+
+macros should evaluate arguments only once
+_bit_byte(0) -> 1
+_bit_mask(1) -> 2
+bitstr_size(2) -> 3
+bit_alloc(3) -> 4
+bit_alloc(4) -> 5
+bit_test(5) -> 6
+bit_set(6) -> 7
+bit_clear(7) -> 8
+bit_nclear(8, 9) -> 10
+bit_nset(10, 11) -> 12
+bit_ffc(12, 0) -> 13
+bit_ffs(13, 0) -> 14
index 7474b96..011e6aa 100644 (file)
@@ -335,3 +335,17 @@ CHI square test
  29   0   2 00100000000000000000000000000100
  30   0   1 01000000000000000000000000000010
  31   1   0 10000000000000000000000000000001
+
+macros should evaluate arguments only once
+_bit_byte(0) -> 1
+_bit_mask(1) -> 2
+bitstr_size(2) -> 3
+bit_alloc(3) -> 4
+bit_alloc(4) -> 5
+bit_test(5) -> 6
+bit_set(6) -> 7
+bit_clear(7) -> 8
+bit_nclear(8, 9) -> 10
+bit_nset(10, 11) -> 12
+bit_ffc(12, 0) -> 13
+bit_ffs(13, 0) -> 14
index 42e55b3..08b46ff 100644 (file)
@@ -488,3 +488,17 @@ CHI square test
  46   0   2 0010000000000000000000000000000000000000000000100
  47   0   1 0100000000000000000000000000000000000000000000010
  48   1   0 1000000000000000000000000000000000000000000000001
+
+macros should evaluate arguments only once
+_bit_byte(0) -> 1
+_bit_mask(1) -> 2
+bitstr_size(2) -> 3
+bit_alloc(3) -> 4
+bit_alloc(4) -> 5
+bit_test(5) -> 6
+bit_set(6) -> 7
+bit_clear(7) -> 8
+bit_nclear(8, 9) -> 10
+bit_nset(10, 11) -> 12
+bit_ffc(12, 0) -> 13
+bit_ffs(13, 0) -> 14
index deb94b6..a2a85cb 100644 (file)
@@ -623,3 +623,17 @@ CHI square test
  61   0   2 0010000000000000000000000000000000000000000000000000000000000100
  62   0   1 0100000000000000000000000000000000000000000000000000000000000010
  63   1   0 1000000000000000000000000000000000000000000000000000000000000001
+
+macros should evaluate arguments only once
+_bit_byte(0) -> 1
+_bit_mask(1) -> 2
+bitstr_size(2) -> 3
+bit_alloc(3) -> 4
+bit_alloc(4) -> 5
+bit_test(5) -> 6
+bit_set(6) -> 7
+bit_clear(7) -> 8
+bit_nclear(8, 9) -> 10
+bit_nset(10, 11) -> 12
+bit_ffc(12, 0) -> 13
+bit_ffs(13, 0) -> 14
index 83cd3fd..3280b31 100644 (file)
@@ -650,3 +650,17 @@ CHI square test
  64   0   2 0010000000000000000000000000000000000000000000000000000000000000100
  65   0   1 0100000000000000000000000000000000000000000000000000000000000000010
  66   1   0 1000000000000000000000000000000000000000000000000000000000000000001
+
+macros should evaluate arguments only once
+_bit_byte(0) -> 1
+_bit_mask(1) -> 2
+bitstr_size(2) -> 3
+bit_alloc(3) -> 4
+bit_alloc(4) -> 5
+bit_test(5) -> 6
+bit_set(6) -> 7
+bit_clear(7) -> 8
+bit_nclear(8, 9) -> 10
+bit_nset(10, 11) -> 12
+bit_ffc(12, 0) -> 13
+bit_ffs(13, 0) -> 14
index 1def322..bdf55cf 100644 (file)
@@ -119,3 +119,17 @@ CHI square test
   5   0   2 00100100
   6   0   1 01000010
   7   1   0 10000001
+
+macros should evaluate arguments only once
+_bit_byte(0) -> 1
+_bit_mask(1) -> 2
+bitstr_size(2) -> 3
+bit_alloc(3) -> 4
+bit_alloc(4) -> 5
+bit_test(5) -> 6
+bit_set(6) -> 7
+bit_clear(7) -> 8
+bit_nclear(0, 1) -> 2
+bit_nset(2, 3) -> 4
+bit_ffc(4, 0) -> 5
+bit_ffs(5, 0) -> 6