#include #include #include #include /* ---------- helpers ---------- */ static int eql_int(const scc_ap_t *ap, isize expected) { return scc_ap_eql( ap, &(scc_ap_t){.capacity = -1, .len = expected < 0 ? -1 : 1, .data.digit = (scc_ap_digit)(expected < 0 ? -(uint64_t)(int64_t)expected : (uint64_t)expected)}); } /* ---------- scc_ap_init / scc_ap_drop ---------- */ void test_init_zero(void) { scc_ap_t ap; scc_ap_init(&ap); TEST_CHECK(ap.capacity == -1); TEST_CHECK(ap.len == 1); TEST_CHECK(ap.data.digit == 0); TEST_CHECK(eql_int(&ap, 0)); } void test_drop_resets(void) { scc_ap_t ap; scc_ap_set_int(&ap, 42); scc_ap_drop(&ap); TEST_CHECK(ap.capacity == -1); TEST_CHECK(ap.len == 1); TEST_CHECK(ap.data.digit == 0); TEST_CHECK(eql_int(&ap, 0)); } /* ---------- scc_ap_set_int ---------- */ void test_set_int_positive(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_int(&ap, 42); TEST_CHECK(eql_int(&ap, 42)); } void test_set_int_negative(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_int(&ap, -42); TEST_CHECK(eql_int(&ap, -42)); } void test_set_int_zero(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_int(&ap, 0); TEST_CHECK(eql_int(&ap, 0)); } void test_set_int_edge(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_int(&ap, 2147483647); /* INT_MAX */ TEST_CHECK(eql_int(&ap, 2147483647)); scc_ap_set_int(&ap, -2147483647 - 1); /* INT_MIN */ TEST_CHECK(eql_int(&ap, -2147483647 - 1)); } /* ---------- scc_ap_set_digit ---------- */ void test_set_digit_basic(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_digit(&ap, 123); TEST_CHECK(eql_int(&ap, 123)); } void test_set_digit_zero(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_digit(&ap, 0); TEST_CHECK(eql_int(&ap, 0)); } void test_set_digit_max(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_digit(&ap, (scc_ap_digit)INTPTR_MAX); TEST_CHECK(eql_int(&ap, INTPTR_MAX)); } /* ---------- scc_ap_from_string ---------- */ void test_from_string_decimal(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "12345", -1, 10); TEST_CHECK(eql_int(&ap, 12345)); } void test_from_string_negative(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "-12345", -1, 10); TEST_CHECK(eql_int(&ap, -12345)); } void test_from_string_hex(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "0xFF", -1, 0); TEST_CHECK(eql_int(&ap, 255)); } void test_from_string_hex_no_prefix(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "FF", -1, 16); TEST_CHECK(eql_int(&ap, 255)); } void test_from_string_octal(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "077", -1, 0); TEST_CHECK(eql_int(&ap, 63)); } void test_from_string_binary(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "0b1010", -1, 0); TEST_CHECK(eql_int(&ap, 10)); } void test_from_string_zero(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "0", -1, 10); TEST_CHECK(eql_int(&ap, 0)); } void test_from_string_empty(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "", -1, 10); TEST_CHECK(eql_int(&ap, 0)); } void test_from_string_negative_zero(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "-0", -1, 10); TEST_CHECK(eql_int(&ap, 0)); /* Should be positive zero */ TEST_CHECK(ap.len > 0); } void test_from_string_len_exact(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "42extra", 2, 10); TEST_CHECK(eql_int(&ap, 42)); } void test_from_string_max(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "9223372036854775807", -1, 10); /* INT64_MAX */ TEST_CHECK(eql_int(&ap, 9223372036854775807LL)); } void test_from_string_min(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_from_string(&ap, "-9223372036854775808", -1, 10); TEST_CHECK(eql_int(&ap, (-9223372036854775807LL - 1))); } /* ---------- scc_ap_add ---------- */ void test_add_basic(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 3); scc_ap_set_int(&b, 5); scc_ap_add(&r, &a, &b); TEST_CHECK(eql_int(&r, 8)); } void test_add_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -3); scc_ap_set_int(&b, 5); scc_ap_add(&r, &a, &b); TEST_CHECK(eql_int(&r, 2)); } void test_add_both_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -3); scc_ap_set_int(&b, -5); scc_ap_add(&r, &a, &b); TEST_CHECK(eql_int(&r, -8)); } void test_add_zero(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 0); scc_ap_add(&r, &a, &b); TEST_CHECK(eql_int(&r, 42)); } void test_add_to_max(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_from_string(&a, "9223372036854775806", -1, 10); scc_ap_set_int(&b, 1); scc_ap_add(&r, &a, &b); TEST_CHECK(eql_int(&r, INTPTR_MAX)); } void test_add_to_min(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); /* INTPTR_MIN + 1 + (-1) = INTPTR_MIN */ scc_ap_from_string(&a, "-9223372036854775807", -1, 10); scc_ap_set_int(&b, -1); scc_ap_add(&r, &a, &b); TEST_CHECK(eql_int(&r, INTPTR_MIN)); } /* ---------- scc_ap_sub ---------- */ void test_sub_basic(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 10); scc_ap_set_int(&b, 3); scc_ap_sub(&r, &a, &b); TEST_CHECK(eql_int(&r, 7)); } void test_sub_negative_result(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 3); scc_ap_set_int(&b, 10); scc_ap_sub(&r, &a, &b); TEST_CHECK(eql_int(&r, -7)); } void test_sub_negatives(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -5); scc_ap_set_int(&b, -3); scc_ap_sub(&r, &a, &b); TEST_CHECK(eql_int(&r, -2)); } void test_sub_zero(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 0); scc_ap_sub(&r, &a, &b); TEST_CHECK(eql_int(&r, 42)); } void test_sub_from_min(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); /* (INTPTR_MIN + 1) - 1 = INTPTR_MIN */ scc_ap_from_string(&a, "-9223372036854775807", -1, 10); scc_ap_set_int(&b, 1); scc_ap_sub(&r, &a, &b); TEST_CHECK(eql_int(&r, INTPTR_MIN)); } /* ---------- scc_ap_mul ---------- */ void test_mul_basic(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 6); scc_ap_set_int(&b, 7); scc_ap_mul(&r, &a, &b); TEST_CHECK(eql_int(&r, 42)); } void test_mul_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -4); scc_ap_set_int(&b, 5); scc_ap_mul(&r, &a, &b); TEST_CHECK(eql_int(&r, -20)); } void test_mul_both_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -4); scc_ap_set_int(&b, -5); scc_ap_mul(&r, &a, &b); TEST_CHECK(eql_int(&r, 20)); } void test_mul_zero(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 0); scc_ap_mul(&r, &a, &b); TEST_CHECK(eql_int(&r, 0)); } void test_mul_one(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 99); scc_ap_set_int(&b, 1); scc_ap_mul(&r, &a, &b); TEST_CHECK(eql_int(&r, 99)); } void test_mul_neg_one(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 99); scc_ap_set_int(&b, -1); scc_ap_mul(&r, &a, &b); TEST_CHECK(eql_int(&r, -99)); } void test_mul_max(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 1); scc_ap_from_string(&b, "9223372036854775807", -1, 10); scc_ap_mul(&r, &a, &b); TEST_CHECK(eql_int(&r, INTPTR_MAX)); } /* ---------- scc_ap_div ---------- */ void test_div_basic(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 6); scc_ap_div(&r, &a, &b); TEST_CHECK(eql_int(&r, 7)); } void test_div_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -42); scc_ap_set_int(&b, 6); scc_ap_div(&r, &a, &b); TEST_CHECK(eql_int(&r, -7)); } void test_div_trunc_toward_zero(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 7); scc_ap_set_int(&b, 3); scc_ap_div(&r, &a, &b); TEST_CHECK(eql_int(&r, 2)); } void test_div_one(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 123); scc_ap_set_int(&b, 1); scc_ap_div(&r, &a, &b); TEST_CHECK(eql_int(&r, 123)); } void test_div_self(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 42); scc_ap_div(&r, &a, &b); TEST_CHECK(eql_int(&r, 1)); } void test_div_zero_dividend(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 0); scc_ap_set_int(&b, 7); scc_ap_div(&r, &a, &b); TEST_CHECK(eql_int(&r, 0)); } /* ---------- scc_ap_mod ---------- */ void test_mod_basic(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 10); scc_ap_set_int(&b, 3); scc_ap_mod(&r, &a, &b); TEST_CHECK(eql_int(&r, 1)); } void test_mod_negative_dividend(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -10); scc_ap_set_int(&b, 3); scc_ap_mod(&r, &a, &b); /* C truncates toward zero: -10 % 3 = -1 */ TEST_CHECK(eql_int(&r, -1)); } void test_mod_self(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 42); scc_ap_mod(&r, &a, &b); TEST_CHECK(eql_int(&r, 0)); } /* ---------- scc_ap_shl / scc_ap_shr / scc_ap_lshr ---------- */ void test_shl_basic(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 3); scc_ap_shl(&r, &a, 2); TEST_CHECK(eql_int(&r, 12)); /* 3 << 2 = 12 */ } void test_shl_negative(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, -3); scc_ap_shl(&r, &a, 2); TEST_CHECK(eql_int(&r, -12)); } void test_shl_zero(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_shl(&r, &a, 0); TEST_CHECK(eql_int(&r, 42)); } void test_shl_by_62(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 1); scc_ap_shl(&r, &a, 62); TEST_CHECK(eql_int(&r, 4611686018427387904LL)); } void test_shr_basic(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 12); scc_ap_shr(&r, &a, 2); TEST_CHECK(eql_int(&r, 3)); /* 12 >> 2 = 3 */ } void test_shr_arithmetic_negative(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, -12); scc_ap_shr(&r, &a, 2); TEST_CHECK(eql_int(&r, -3)); /* arithmetic: -12 >> 2 = -3 */ } void test_shr_arithmetic_negative_rounding(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, -7); scc_ap_shr(&r, &a, 2); TEST_CHECK(eql_int(&r, -2)); /* arithmetic: -7 >> 2 = -2 (rounds down) */ } void test_shr_zero_shift(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, -42); scc_ap_shr(&r, &a, 0); TEST_CHECK(eql_int(&r, -42)); } void test_lshr_basic(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 12); scc_ap_lshr(&r, &a, 2); TEST_CHECK(eql_int(&r, 3)); /* 12 >> 2 = 3 */ } void test_lshr_negative(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, -1); /* 0xFFFFFFFFFFFFFFFF */ scc_ap_lshr(&r, &a, 63); TEST_CHECK(eql_int(&r, 1)); /* 0xFFFFFFFFFFFFFFFF >> 63 = 1 */ } void test_lshr_negative_bits(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, -8); /* 0xFFFFFFFFFFFFFFF8 */ scc_ap_lshr(&r, &a, 2); /* 0xFFFFFFFFFFFFFFF8 >> 2 = 0x3FFFFFFFFFFFFFFE = 4611686018427387902 */ TEST_CHECK(eql_int(&r, 4611686018427387902LL)); } /* ---------- bitwise ---------- */ void test_and_basic(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 5); scc_ap_set_int(&b, 3); scc_ap_and(&r, &a, &b); TEST_CHECK(eql_int(&r, 1)); /* 5 & 3 = 1 */ } void test_and_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -5); scc_ap_set_int(&b, 3); scc_ap_and(&r, &a, &b); /* -5 = 0xFFFFFFFB, & 3 = 0x00000003 = 3 */ TEST_CHECK(eql_int(&r, 3)); } void test_and_zero(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 0); scc_ap_and(&r, &a, &b); TEST_CHECK(eql_int(&r, 0)); } void test_or_basic(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 5); scc_ap_set_int(&b, 3); scc_ap_or(&r, &a, &b); TEST_CHECK(eql_int(&r, 7)); /* 5 | 3 = 7 */ } void test_or_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -5); scc_ap_set_int(&b, 3); scc_ap_or(&r, &a, &b); TEST_CHECK(eql_int(&r, -5)); /* -5 | 3 = -5 */ } void test_xor_basic(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, 5); scc_ap_set_int(&b, 3); scc_ap_xor(&r, &a, &b); TEST_CHECK(eql_int(&r, 6)); /* 5 ^ 3 = 6 */ } void test_xor_negative(void) { scc_ap_t a, b, r; scc_ap_init(&a); scc_ap_init(&b); scc_ap_init(&r); scc_ap_set_int(&a, -5); scc_ap_set_int(&b, 3); scc_ap_xor(&r, &a, &b); TEST_CHECK(eql_int(&r, -8)); /* -5 ^ 3 = -8 */ } void test_not_basic(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 5); scc_ap_not(&r, &a); TEST_CHECK(eql_int(&r, -6)); /* ~5 = -6 */ } void test_not_neg_one(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, -1); scc_ap_not(&r, &a); TEST_CHECK(eql_int(&r, 0)); /* ~(-1) = 0 */ } void test_not_zero(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 0); scc_ap_not(&r, &a); TEST_CHECK(eql_int(&r, -1)); /* ~0 = -1 */ } /* ---------- scc_ap_neg ---------- */ void test_neg_positive(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 42); scc_ap_neg(&r, &a); TEST_CHECK(eql_int(&r, -42)); } void test_neg_negative(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, -42); scc_ap_neg(&r, &a); TEST_CHECK(eql_int(&r, 42)); } void test_neg_zero(void) { scc_ap_t a, r; scc_ap_init(&a); scc_ap_init(&r); scc_ap_set_int(&a, 0); scc_ap_neg(&r, &a); TEST_CHECK(eql_int(&r, 0)); } /* ---------- scc_ap_cmp ---------- */ void test_cmp_equal(void) { scc_ap_t a, b; scc_ap_init(&a); scc_ap_init(&b); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 42); TEST_CHECK(scc_ap_cmp(&a, &b) == 0); } void test_cmp_less(void) { scc_ap_t a, b; scc_ap_init(&a); scc_ap_init(&b); scc_ap_set_int(&a, 3); scc_ap_set_int(&b, 5); TEST_CHECK(scc_ap_cmp(&a, &b) < 0); } void test_cmp_greater(void) { scc_ap_t a, b; scc_ap_init(&a); scc_ap_init(&b); scc_ap_set_int(&a, 5); scc_ap_set_int(&b, 3); TEST_CHECK(scc_ap_cmp(&a, &b) > 0); } void test_cmp_neg_vs_pos(void) { scc_ap_t a, b; scc_ap_init(&a); scc_ap_init(&b); scc_ap_set_int(&a, -5); scc_ap_set_int(&b, 3); TEST_CHECK(scc_ap_cmp(&a, &b) < 0); } /* ---------- scc_ap_is_zero ---------- */ void test_is_zero_true(void) { scc_ap_t ap; scc_ap_init(&ap); TEST_CHECK(scc_ap_is_zero(&ap) != 0); } void test_is_zero_false_pos(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_int(&ap, 42); TEST_CHECK(scc_ap_is_zero(&ap) == 0); } void test_is_zero_false_neg(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_set_int(&ap, -42); TEST_CHECK(scc_ap_is_zero(&ap) == 0); } /* ---------- scc_ap_eql ---------- */ void test_eql_equal(void) { scc_ap_t a, b; scc_ap_init(&a); scc_ap_init(&b); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 42); TEST_CHECK(scc_ap_eql(&a, &b) != 0); } void test_eql_not_equal(void) { scc_ap_t a, b; scc_ap_init(&a); scc_ap_init(&b); scc_ap_set_int(&a, 42); scc_ap_set_int(&b, 43); TEST_CHECK(scc_ap_eql(&a, &b) == 0); } void test_eql_neg_vs_pos(void) { scc_ap_t a, b; scc_ap_init(&a); scc_ap_init(&b); scc_ap_set_int(&a, -42); scc_ap_set_int(&b, 42); TEST_CHECK(scc_ap_eql(&a, &b) == 0); } void test_eql_both_zero(void) { scc_ap_t a, b; scc_ap_init(&a); scc_ap_init(&b); /* +0 == 0 */ scc_ap_from_string(&a, "0", -1, 10); scc_ap_from_string(&b, "-0", -1, 10); TEST_CHECK(scc_ap_eql(&a, &b) != 0); } /* ---------- scc_ap_with_bits ---------- */ void test_with_bits_small(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_with_bits(&ap, 1); TEST_CHECK(ap.capacity == -1); } void test_with_bits_64(void) { scc_ap_t ap; scc_ap_init(&ap); scc_ap_with_bits(&ap, 64); TEST_CHECK(ap.capacity == -1); } /* ---------- scc_ap_dump ---------- */ typedef struct { char buf[128]; int pos; } dump_ctx_t; static void dump_char(char ch, void *user_data) { dump_ctx_t *ctx = (dump_ctx_t *)user_data; if (ctx->pos < (int)sizeof(ctx->buf) - 1) ctx->buf[ctx->pos++] = ch; } void test_dump_positive(void) { scc_ap_t ap; dump_ctx_t ctx; scc_ap_init(&ap); scc_ap_set_int(&ap, 12345); ctx.pos = 0; ctx.buf[0] = '\0'; scc_ap_dump(&ap, dump_char, &ctx); ctx.buf[ctx.pos] = '\0'; TEST_CHECK(strcmp(ctx.buf, "12345") == 0); } void test_dump_negative(void) { scc_ap_t ap; dump_ctx_t ctx; scc_ap_init(&ap); scc_ap_set_int(&ap, -12345); ctx.pos = 0; ctx.buf[0] = '\0'; scc_ap_dump(&ap, dump_char, &ctx); ctx.buf[ctx.pos] = '\0'; TEST_CHECK(strcmp(ctx.buf, "-12345") == 0); } void test_dump_zero(void) { scc_ap_t ap; dump_ctx_t ctx; scc_ap_init(&ap); ctx.pos = 0; ctx.buf[0] = '\0'; scc_ap_dump(&ap, dump_char, &ctx); ctx.buf[ctx.pos] = '\0'; TEST_CHECK(strcmp(ctx.buf, "0") == 0); } void test_dump_max(void) { scc_ap_t ap; dump_ctx_t ctx; scc_ap_init(&ap); scc_ap_from_string(&ap, "9223372036854775807", -1, 10); ctx.pos = 0; ctx.buf[0] = '\0'; scc_ap_dump(&ap, dump_char, &ctx); ctx.buf[ctx.pos] = '\0'; TEST_CHECK(strcmp(ctx.buf, "9223372036854775807") == 0); } void test_dump_min(void) { scc_ap_t ap; dump_ctx_t ctx; scc_ap_init(&ap); scc_ap_from_string(&ap, "-9223372036854775808", -1, 10); ctx.pos = 0; ctx.buf[0] = '\0'; scc_ap_dump(&ap, dump_char, &ctx); ctx.buf[ctx.pos] = '\0'; TEST_CHECK(strcmp(ctx.buf, "-9223372036854775808") == 0); } /* ---------- test list ---------- */ TEST_LIST = { /* init / drop */ {"test_init_zero", test_init_zero}, {"test_drop_resets", test_drop_resets}, /* set_int */ {"test_set_int_positive", test_set_int_positive}, {"test_set_int_negative", test_set_int_negative}, {"test_set_int_zero", test_set_int_zero}, {"test_set_int_edge", test_set_int_edge}, /* set_digit */ {"test_set_digit_basic", test_set_digit_basic}, {"test_set_digit_zero", test_set_digit_zero}, {"test_set_digit_max", test_set_digit_max}, /* from_string */ {"test_from_string_decimal", test_from_string_decimal}, {"test_from_string_negative", test_from_string_negative}, {"test_from_string_hex", test_from_string_hex}, {"test_from_string_hex_no_prefix", test_from_string_hex_no_prefix}, {"test_from_string_octal", test_from_string_octal}, {"test_from_string_binary", test_from_string_binary}, {"test_from_string_zero", test_from_string_zero}, {"test_from_string_empty", test_from_string_empty}, {"test_from_string_negative_zero", test_from_string_negative_zero}, {"test_from_string_len_exact", test_from_string_len_exact}, {"test_from_string_max", test_from_string_max}, {"test_from_string_min", test_from_string_min}, /* add */ {"test_add_basic", test_add_basic}, {"test_add_negative", test_add_negative}, {"test_add_both_negative", test_add_both_negative}, {"test_add_zero", test_add_zero}, {"test_add_to_max", test_add_to_max}, {"test_add_to_min", test_add_to_min}, /* sub */ {"test_sub_basic", test_sub_basic}, {"test_sub_negative_result", test_sub_negative_result}, {"test_sub_negatives", test_sub_negatives}, {"test_sub_zero", test_sub_zero}, {"test_sub_from_min", test_sub_from_min}, /* mul */ {"test_mul_basic", test_mul_basic}, {"test_mul_negative", test_mul_negative}, {"test_mul_both_negative", test_mul_both_negative}, {"test_mul_zero", test_mul_zero}, {"test_mul_one", test_mul_one}, {"test_mul_neg_one", test_mul_neg_one}, {"test_mul_max", test_mul_max}, /* div */ {"test_div_basic", test_div_basic}, {"test_div_negative", test_div_negative}, {"test_div_trunc_toward_zero", test_div_trunc_toward_zero}, {"test_div_one", test_div_one}, {"test_div_self", test_div_self}, {"test_div_zero_dividend", test_div_zero_dividend}, /* mod */ {"test_mod_basic", test_mod_basic}, {"test_mod_negative_dividend", test_mod_negative_dividend}, {"test_mod_self", test_mod_self}, /* shl / shr / lshr */ {"test_shl_basic", test_shl_basic}, {"test_shl_negative", test_shl_negative}, {"test_shl_zero", test_shl_zero}, {"test_shl_by_62", test_shl_by_62}, {"test_shr_basic", test_shr_basic}, {"test_shr_arithmetic_negative", test_shr_arithmetic_negative}, {"test_shr_arithmetic_negative_rounding", test_shr_arithmetic_negative_rounding}, {"test_shr_zero_shift", test_shr_zero_shift}, {"test_lshr_basic", test_lshr_basic}, {"test_lshr_negative", test_lshr_negative}, {"test_lshr_negative_bits", test_lshr_negative_bits}, /* bitwise */ {"test_and_basic", test_and_basic}, {"test_and_negative", test_and_negative}, {"test_and_zero", test_and_zero}, {"test_or_basic", test_or_basic}, {"test_or_negative", test_or_negative}, {"test_xor_basic", test_xor_basic}, {"test_xor_negative", test_xor_negative}, {"test_not_basic", test_not_basic}, {"test_not_neg_one", test_not_neg_one}, {"test_not_zero", test_not_zero}, /* neg */ {"test_neg_positive", test_neg_positive}, {"test_neg_negative", test_neg_negative}, {"test_neg_zero", test_neg_zero}, /* cmp */ {"test_cmp_equal", test_cmp_equal}, {"test_cmp_less", test_cmp_less}, {"test_cmp_greater", test_cmp_greater}, {"test_cmp_neg_vs_pos", test_cmp_neg_vs_pos}, /* is_zero */ {"test_is_zero_true", test_is_zero_true}, {"test_is_zero_false_pos", test_is_zero_false_pos}, {"test_is_zero_false_neg", test_is_zero_false_neg}, /* eql */ {"test_eql_equal", test_eql_equal}, {"test_eql_not_equal", test_eql_not_equal}, {"test_eql_neg_vs_pos", test_eql_neg_vs_pos}, {"test_eql_both_zero", test_eql_both_zero}, /* with_bits */ {"test_with_bits_small", test_with_bits_small}, {"test_with_bits_64", test_with_bits_64}, /* dump */ {"test_dump_positive", test_dump_positive}, {"test_dump_negative", test_dump_negative}, {"test_dump_zero", test_dump_zero}, {"test_dump_max", test_dump_max}, {"test_dump_min", test_dump_min}, {nullptr, nullptr}, };