Mercurial > libjeffpc
view tests/test_sexpr_eval.c @ 862:6075f43a5d72
Enable -Wswitch-enum warnings
This compiler option enables warnings about switch statements on enums that
do not exhaustively list every value. The default case does *not* squelch
the warning.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Tue, 04 Apr 2023 20:29:03 -0400 |
parents | 7544e9990bc1 |
children |
line wrap: on
line source
/* * Copyright (c) 2016-2017,2023 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include <jeffpc/types.h> #include <jeffpc/sexpr.h> #include "test.c" static inline struct val *safe_dump(struct val *val) { int ret; ret = sexpr_dump_file(stderr, val, false); if (ret) fail("%s: failed to dump value: %s", xstrerror(ret)); return val; } static inline struct val *op0(char *op) { struct val *arr[1]; struct val *ret; arr[0] = VAL_ALLOC_SYM_STATIC(op); ret = sexpr_array_to_list(arr, ARRAY_LEN(arr)); return safe_dump(ret); } static inline struct val *op1(char *op, struct val *a) { struct val *arr[2]; struct val *ret; arr[0] = VAL_ALLOC_SYM_STATIC(op); arr[1] = a; ret = sexpr_array_to_list(arr, ARRAY_LEN(arr)); return safe_dump(ret); } static inline struct val *op2(char *op, struct val *a, struct val *b) { struct val *arr[3]; struct val *ret; arr[0] = VAL_ALLOC_SYM_STATIC(op); arr[1] = a; arr[2] = b; ret = sexpr_array_to_list(arr, ARRAY_LEN(arr)); return safe_dump(ret); } static inline struct val *op3(char *op, struct val *a, struct val *b, struct val *c) { struct val *arr[4]; struct val *ret; arr[0] = VAL_ALLOC_SYM_STATIC(op); arr[1] = a; arr[2] = b; arr[3] = c; ret = sexpr_array_to_list(arr, ARRAY_LEN(arr)); return safe_dump(ret); } static void test_int_op(char *opname, enum val_type type, uint64_t expected, struct val *expr) { struct val *res; int ret; res = sexpr_eval(expr, NULL); fprintf(stderr, " -> "); ret = sexpr_dump_file(stderr, res, false); if (ret) fail("failed to dump result: %s", xstrerror(ret)); fprintf(stderr, "\n"); ASSERT3U(res->type, ==, type); switch (type) { case VT_BOOL: ASSERT3U(res->b, ==, expected); break; case VT_INT: ASSERT3U(res->i, ==, expected); break; case VT_NULL: case VT_STR: case VT_SYM: case VT_CHAR: case VT_BLOB: case VT_CONS: case VT_ARRAY: case VT_NVL: default: fail("unhandled val type %u", type); } val_putref(res); } #define TEST_BOOL_OP0(n, e) test_int_op((n), VT_BOOL, (e), op0(n)) #define TEST_BOOL_OP1(n, e, v1) test_int_op((n), VT_BOOL, (e), op1((n), \ VAL_ALLOC_BOOL(v1))) #define TEST_BOOL_OP2(n, e, v1, v2) test_int_op((n), VT_BOOL, (e), op2((n), \ VAL_ALLOC_BOOL(v1), \ VAL_ALLOC_BOOL(v2))) #define TEST_BOOL_OP3(n, e, v1, v2, v3) test_int_op((n), VT_BOOL, (e), op3((n), \ VAL_ALLOC_BOOL(v1), \ VAL_ALLOC_BOOL(v2), \ VAL_ALLOC_BOOL(v3))) #define TEST_INT_OP0(n, e) test_int_op((n), VT_INT, (e), op0(n)) #define TEST_INT_OP1(n, e, v1) test_int_op((n), VT_INT, (e), op1((n), \ VAL_ALLOC_INT(v1))) #define TEST_INT_OP2(n, e, v1, v2) test_int_op((n), VT_INT, (e), op2((n), \ VAL_ALLOC_INT(v1), \ VAL_ALLOC_INT(v2))) #define TEST_INT_OP3(n, e, v1, v2, v3) test_int_op((n), VT_INT, (e), op3((n), \ VAL_ALLOC_INT(v1), \ VAL_ALLOC_INT(v2), \ VAL_ALLOC_INT(v3))) static void test_bools(void) { int i, j, k; fprintf(stderr, "Testing booleans...\n"); TEST_BOOL_OP0("or", false); TEST_BOOL_OP0("and", true); for (i = 0; i < 2; i++) { TEST_BOOL_OP1("or", !!i, !!i); TEST_BOOL_OP1("and", !!i, !!i); } for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { TEST_BOOL_OP2("or", (!!i) || (!!j), !!i, !!j); TEST_BOOL_OP2("and", (!!i) && (!!j), !!i, !!j); } } for (i = 0; i < 2; i++) { for (j = 0; j < 2; j++) { for (k = 0; k < 2; k++) { TEST_BOOL_OP3("or", (!!i) || (!!j) || (!!k), !!i, !!j, !!k); TEST_BOOL_OP3("and", (!!i) && (!!j) && (!!k), !!i, !!j, !!k); } } } } static void test_ints(void) { int i, j, k; fprintf(stderr, "Testing integers...\n"); TEST_INT_OP0("+", 0); TEST_INT_OP0("*", 1); for (i = 0; i < 3; i++) { TEST_INT_OP1("+", i, i); TEST_INT_OP1("*", i, i); } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { TEST_INT_OP2("+", i + j, i, j); TEST_INT_OP2("*", i * j, i, j); } } for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { for (k = 0; k < 3; k++) { TEST_INT_OP3("+", i + j + k, i, j, k); TEST_INT_OP3("*", i * j * k, i, j, k); } } } } void test(void) { test_bools(); test_ints(); }