From 6ce03a4f1b229e605da08b073fad6f7c0fe8bf10 Mon Sep 17 00:00:00 2001 From: Christopher Peplin Date: Sun, 29 Dec 2013 11:48:24 -0500 Subject: [PATCH] Split up 8 byte wrappers from generic bit array functions. --- src/bitfield/8byte.c | 56 ++++++++++++ src/bitfield/8byte.h | 74 ++++++++++++++++ src/bitfield/bitfield.c | 50 ----------- src/bitfield/bitfield.h | 59 ------------- tests/8byte_tests.c | 225 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/bitfield_tests.c | 202 ------------------------------------------- 6 files changed, 355 insertions(+), 311 deletions(-) create mode 100644 src/bitfield/8byte.c create mode 100644 src/bitfield/8byte.h create mode 100644 tests/8byte_tests.c diff --git a/src/bitfield/8byte.c b/src/bitfield/8byte.c new file mode 100644 index 00000000..0f249d93 --- /dev/null +++ b/src/bitfield/8byte.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +uint64_t bitmask(const uint8_t numBits) { + return (((uint64_t)0x1) << numBits) - 1; +} + +static uint16_t bitsToBytes(uint32_t bits) { + uint8_t byte_count = bits / CHAR_BIT; + if(bits % CHAR_BIT != 0) { + ++byte_count; + } + return byte_count; +} + +uint64_t getBitField(uint64_t data, const uint16_t startBit, + const uint16_t numBits, bool bigEndian) { + uint8_t result[8] = {0}; + if(!bigEndian) { + data = __builtin_bswap64(data); + } + copyBitsRightAligned((const uint8_t*)&data, sizeof(data), startBit, numBits, + result, sizeof(result)); + uint64_t int_result = 0; + + if(!bigEndian) { + // we need to swap the byte order of the array to get it into a + // uint64_t, but it's been right aligned so we have to be more careful + for(int i = 0; i < bitsToBytes(numBits); i++) { + int_result |= result[bitsToBytes(numBits) - i - 1] << (CHAR_BIT * i); + } + } else { + int_result = *(uint64_t*)result; + } + return int_result; +} + +/** + * TODO it would be nice to have a warning if you call with this a value that + * won't fit in the number of bits you've specified it should use. + */ +void setBitField(uint64_t* data, uint64_t value, const uint16_t startPos, + const uint16_t numBits) { + int shiftDistance = 64 - startPos - numBits; + value <<= shiftDistance; + *data &= ~(bitmask(numBits) << shiftDistance); + *data |= value; +} + +uint8_t nthByte(const uint64_t source, const uint16_t byteNum) { + return (source >> (64 - ((byteNum + 1) * CHAR_BIT))) & 0xFF; +} + diff --git a/src/bitfield/8byte.h b/src/bitfield/8byte.h new file mode 100644 index 00000000..13b6aff3 --- /dev/null +++ b/src/bitfield/8byte.h @@ -0,0 +1,74 @@ +#ifndef __8BYTE_H__ +#define __8BYTE_H__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// TODO using uint64_t everywhere for CAN message payload is kind of cute, but +// in actuality a CAN message may have a smaller payload, and it makes all of +// these functions not applicable to other data sizes. It's also fairly +// inefficient on 32-bit platforms. how much work is it to switch vi-firmware +// to using uint8_t*? + +/* Public: Reads a subset of bits from a byte array. + * + * data - the bytes in question. + * startPos - the starting index of the bit field (beginning from 0). + * numBits - the width of the bit field to extract. + * bigEndian - if the data passed in is little endian, set this to false and it + * will be flipped before grabbing the bit field. + * + * Bit fields are positioned according to big-endian bit layout, but inside the + * bit field, values are represented as little-endian. Therefore, to get the bit + * field, we swap the overall byte order if bigEndian == false and + * use the value we find in the field (assuming the embedded platform is little + * endian). + * + * For example, the bit layout of the value "42" (i.e. 00101010 set at position + * 14 with length 6 is: + * + * 000000000000001010100000000000000000000000000000000000000000000 + * + * and the same value and position but with length 8 is: + * + * 000000000000000010101000000000000000000000000000000000000000000 + * + * If the architecture where is code is running is little-endian, the input data + * will be swapped before grabbing the bit field. + * + * Examples + * + * uint64_t value = getBitField(data, 2, 4); + * + * Returns the value of the requested bit field. + */ +uint64_t getBitField(uint64_t data, const uint16_t startPos, + const uint16_t numBits, bool bigEndian); + +/* Public: Set the bit field in the given data array to the new value. + * + * data - a byte array with size at least startPos + numBits. + * value - the value to set in the bit field. + * startPos - the starting index of the bit field (beginning from 0). + */ +void setBitField(uint64_t* data, uint64_t value, const uint16_t startPos, + const uint16_t numBits); + +/* Public: Retreive the nth byte out of 8 bytes in a uint64_t. + * + * source - the source data to retreive the byte from. + * byteNum - the index of the byte, starting at 0 and assuming big-endian order. + * + * Returns the requested byte from the source bytes. + */ +uint8_t nthByte(const uint64_t source, const uint16_t byteNum); + +#ifdef __cplusplus +} +#endif + +#endif // __8BYTE_H__ diff --git a/src/bitfield/bitfield.c b/src/bitfield/bitfield.c index 934d5a6a..3bf00ac0 100644 --- a/src/bitfield/bitfield.c +++ b/src/bitfield/bitfield.c @@ -5,56 +5,6 @@ #define NIBBLE_SIZE (CHAR_BIT / 2) -uint64_t bitmask(const uint8_t numBits) { - return (((uint64_t)0x1) << numBits) - 1; -} - -static uint16_t bitsToBytes(uint32_t bits) { - uint8_t byte_count = bits / CHAR_BIT; - if(bits % CHAR_BIT != 0) { - ++byte_count; - } - return byte_count; -} - -uint64_t getBitField(uint64_t data, const uint16_t startBit, - const uint16_t numBits, bool bigEndian) { - uint8_t result[8] = {0}; - if(!bigEndian) { - data = __builtin_bswap64(data); - } - copyBitsRightAligned((const uint8_t*)&data, sizeof(data), startBit, numBits, - result, sizeof(result)); - uint64_t int_result = 0; - - if(!bigEndian) { - // we need to swap the byte order of the array to get it into a - // uint64_t, but it's been right aligned so we have to be more careful - for(int i = 0; i < bitsToBytes(numBits); i++) { - int_result |= result[bitsToBytes(numBits) - i - 1] << (CHAR_BIT * i); - } - } else { - int_result = *(uint64_t*)result; - } - return int_result; -} - -/** - * TODO it would be nice to have a warning if you call with this a value that - * won't fit in the number of bits you've specified it should use. - */ -void setBitField(uint64_t* data, uint64_t value, const uint16_t startPos, - const uint16_t numBits) { - int shiftDistance = 64 - startPos - numBits; - value <<= shiftDistance; - *data &= ~(bitmask(numBits) << shiftDistance); - *data |= value; -} - -uint8_t nthByte(const uint64_t source, const uint16_t byteNum) { - return (source >> (64 - ((byteNum + 1) * CHAR_BIT))) & 0xFF; -} - uint8_t getNibble(const uint8_t source[], const uint8_t source_length, const uint8_t nibble_index) { uint8_t byte_index = nibble_index / 2; diff --git a/src/bitfield/bitfield.h b/src/bitfield/bitfield.h index 45e3ba26..6f5f1c18 100644 --- a/src/bitfield/bitfield.h +++ b/src/bitfield/bitfield.h @@ -108,65 +108,6 @@ bool copyBitsRightAligned(const uint8_t source[], const uint16_t source_length, const uint16_t offset, const uint16_t bit_count, uint8_t* destination, const uint16_t destination_length); -// TODO using uint64_t everywhere for CAN message payload is kind of cute, but -// in actuality a CAN message may have a smaller payload, and it makes all of -// these functions not applicable to other data sizes. It's also fairly -// inefficient on 32-bit platforms. how much work is it to switch vi-firmware -// to using uint8_t*? - -/* Public: Reads a subset of bits from a byte array. - * - * data - the bytes in question. - * startPos - the starting index of the bit field (beginning from 0). - * numBits - the width of the bit field to extract. - * bigEndian - if the data passed in is little endian, set this to false and it - * will be flipped before grabbing the bit field. - * - * Bit fields are positioned according to big-endian bit layout, but inside the - * bit field, values are represented as little-endian. Therefore, to get the bit - * field, we swap the overall byte order if bigEndian == false and - * use the value we find in the field (assuming the embedded platform is little - * endian). - * - * For example, the bit layout of the value "42" (i.e. 00101010 set at position - * 14 with length 6 is: - * - * 000000000000001010100000000000000000000000000000000000000000000 - * - * and the same value and position but with length 8 is: - * - * 000000000000000010101000000000000000000000000000000000000000000 - * - * If the architecture where is code is running is little-endian, the input data - * will be swapped before grabbing the bit field. - * - * Examples - * - * uint64_t value = getBitField(data, 2, 4); - * - * Returns the value of the requested bit field. - */ -uint64_t getBitField(uint64_t data, const uint16_t startPos, - const uint16_t numBits, bool bigEndian); - -/* Public: Set the bit field in the given data array to the new value. - * - * data - a byte array with size at least startPos + numBits. - * value - the value to set in the bit field. - * startPos - the starting index of the bit field (beginning from 0). - */ -void setBitField(uint64_t* data, uint64_t value, const uint16_t startPos, - const uint16_t numBits); - -/* Public: Retreive the nth byte out of 8 bytes in a uint64_t. - * - * source - the source data to retreive the byte from. - * byteNum - the index of the byte, starting at 0 and assuming big-endian order. - * - * Returns the requested byte from the source bytes. - */ -uint8_t nthByte(const uint64_t source, const uint16_t byteNum); - #ifdef __cplusplus } #endif diff --git a/tests/8byte_tests.c b/tests/8byte_tests.c new file mode 100644 index 00000000..140c4efb --- /dev/null +++ b/tests/8byte_tests.c @@ -0,0 +1,225 @@ +#include +#include +#include + +START_TEST (test_large_bitmask) +{ + // yeah, this isn't a public method but I wanted to unit test it to track + // down a bug + extern uint64_t bitmask(int numBits); + uint64_t result = bitmask(32); + fail_if(result != 0xffffffff); +} +END_TEST + +START_TEST (test_one_bit_not_swapped) +{ + uint64_t data = 0x80; + uint64_t result = getBitField(data, 0, 1, false); + fail_if(result == 1); +} +END_TEST + +START_TEST (test_one_bit) +{ + uint64_t data = 0x8000000000000000; + uint64_t result = getBitField(data, 0, 1, false); + fail_unless(result == 0x1, + "First bit in 0x%llx was 0x%llx instead of 0x1", data, result); +} +END_TEST + +START_TEST (test_32_bit_parse) +{ + uint64_t data = 0x0402574d555a0401; + uint64_t result = getBitField(data, 16, 32, false); + uint64_t expectedValue = 0x574d555a; + fail_unless(result == expectedValue, + "Field retrieved in 0x%llx was 0x%llx instead of 0x%llx", data, + result, expectedValue); +} +END_TEST + +START_TEST (test_16_bit_parse) +{ + uint64_t data = 0xF34DFCFF00000000; + uint64_t result = getBitField(data, 16, 16, false); + uint64_t expectedValue = 0xFCFF; + fail_unless(result == expectedValue, + "Field retrieved in 0x%llx was 0x%llx instead of 0x%llx", data, + result, expectedValue); +} +END_TEST + +START_TEST (test_one_byte) +{ + uint64_t data = 0xFA00000000000000; + uint64_t result = getBitField(data, 0, 4, false); + fail_unless(result == 0xF, + "First 4 bits in 0x%llx was 0x%llx instead of 0xF", data, result); + result = getBitField(data, 4, 4, false); + fail_unless(result == 0xA, + "First 4 bits in 0x%llx was 0x%llx instead of 0xA", data, result); + result = getBitField(data, 0, 8, false); + fail_unless(result == 0xFA, + "All bits in 0x%llx were 0x%llx instead of 0x%llx", data, result, data); +} +END_TEST + +START_TEST (test_multi_byte) +{ + uint64_t data = 0x12FA000000000000; + uint64_t result = getBitField(data, 0, 4, false); + fail_unless(result == 0x1, + "First 4 bits in 0x%llx was 0x%llx instead of 0xF", (data >> 60) & 0xF, + result); + result = getBitField(data, 4, 4, false); + fail_unless(result == 0x2, + "Second 4 bits in 0x%llx was 0x%llx instead of 0xA", (data >> 56) & 0xF, + result); + result = getBitField(data, 8, 4, false); + fail_unless(result == 0xF, + "First 4 bits in 0x%llx was 0x%llx instead of 0x1", (data >> 52) & 0xF, + result); + result = getBitField(data, 12, 4, false); + fail_unless(result == 0xA, + "Second 4 bits in 0x%llx was 0x%llx instead of 0x2", (data >> 48) % 0xF, + result); +} +END_TEST + +START_TEST (test_get_multi_byte) +{ + uint64_t data = 0x12FA000000000000; + uint64_t result = getBitField(data, 0, 9, false); + ck_assert_int_eq(result, 0x25); +} +END_TEST + +START_TEST (test_get_off_byte_boundary) +{ + uint64_t data = 0x000012FA00000000; + uint64_t result = getBitField(data, 12, 8, false); + ck_assert_int_eq(result, 0x01); +} END_TEST + +START_TEST (test_set_field) +{ + uint64_t data = 0; + setBitField(&data, 1, 0, 1); + uint64_t result = getBitField(data, 0, 1, false); + ck_assert_int_eq(result, 0x1); + data = 0; + setBitField(&data, 1, 1, 1); + result = getBitField(data, 1, 1, false); + ck_assert_int_eq(result, 0x1); + + data = 0; + setBitField(&data, 0xf, 3, 4); + result = getBitField(data, 3, 4, false); + ck_assert_int_eq(result, 0xf); +} +END_TEST + +START_TEST (test_set_doesnt_clobber_existing_data) +{ + uint64_t data = 0xFFFC4DF300000000; + setBitField(&data, 0x4fc8, 16, 16); + uint64_t result = getBitField(data, 16, 16, false); + fail_unless(result == 0x4fc8, + "Field retrieved in 0x%llx was 0x%llx instead of 0x%x", data, result, + 0xc84f); + + data = 0x8000000000000000; + setBitField(&data, 1, 21, 1); + fail_unless(data == 0x8000040000000000LLU, + "Expected combined value 0x8000040000000000 but got 0x%llx%llx", + data >> 32, data); +} +END_TEST + +START_TEST (test_set_off_byte_boundary) +{ + uint64_t data = 0xFFFC4DF300000000; + setBitField(&data, 0x12, 12, 8); + uint64_t result = getBitField(data, 12, 12, false); + ck_assert_int_eq(result,0x12d); +} +END_TEST + +START_TEST (test_set_odd_number_of_bits) +{ + uint64_t data = 0xFFFC4DF300000000LLU; + setBitField(&data, 0x12, 11, 5); + uint64_t result = getBitField(data, 11, 5, false); + fail_unless(result == 0x12, + "Field set in 0x%llx%llx%llx%llx was 0x%llx instead of 0x%llx", data, result, + 0x12); + + data = 0xFFFC4DF300000000LLU; + setBitField(&data, 0x2, 11, 5); + result = getBitField(data, 11, 5, false); + fail_unless(result == 0x2, + "Field set in 0x%llx%llx%llx%llx was 0x%llx instead of 0x%llx", data, result, + 0x2); +} +END_TEST + +START_TEST(test_nth_byte) +{ + uint64_t data = 0x00000000F34DFCFF; + uint8_t result = nthByte(data, 0); + uint8_t expected = 0x0; + ck_assert_int_eq(result, expected); + + result = nthByte(data, 4); + expected = 0xF3; + ck_assert_int_eq(result, expected); + + result = nthByte(data, 5); + expected = 0x4D; + ck_assert_int_eq(result, expected); + + result = nthByte(data, 6); + expected = 0xFC; + ck_assert_int_eq(result, expected); + + result = nthByte(data, 7); + expected = 0xFF; + ck_assert_int_eq(result, expected); +} +END_TEST + +Suite* bitfieldSuite(void) { + Suite* s = suite_create("bitfield"); + TCase *tc_core = tcase_create("core"); + tcase_add_test(tc_core, test_large_bitmask); + tcase_add_test(tc_core, test_one_bit); + tcase_add_test(tc_core, test_one_bit_not_swapped); + tcase_add_test(tc_core, test_one_byte); + tcase_add_test(tc_core, test_16_bit_parse); + tcase_add_test(tc_core, test_32_bit_parse); + tcase_add_test(tc_core, test_multi_byte); + tcase_add_test(tc_core, test_get_multi_byte); + tcase_add_test(tc_core, test_get_off_byte_boundary); + tcase_add_test(tc_core, test_set_field); + tcase_add_test(tc_core, test_set_doesnt_clobber_existing_data); + tcase_add_test(tc_core, test_set_off_byte_boundary); + tcase_add_test(tc_core, test_set_odd_number_of_bits); + tcase_add_test(tc_core, test_nth_byte); + suite_add_tcase(s, tc_core); + + return s; +} + +int main(void) { + int numberFailed; + Suite* s = bitfieldSuite(); + SRunner *sr = srunner_create(s); + // Don't fork so we can actually use gdb + srunner_set_fork_status(sr, CK_NOFORK); + srunner_run_all(sr, CK_NORMAL); + numberFailed = srunner_ntests_failed(sr); + srunner_free(sr); + return (numberFailed == 0) ? 0 : 1; +} diff --git a/tests/bitfield_tests.c b/tests/bitfield_tests.c index 00a28a36..f6287c19 100644 --- a/tests/bitfield_tests.c +++ b/tests/bitfield_tests.c @@ -2,194 +2,6 @@ #include #include -START_TEST (test_large_bitmask) -{ - // yeah, this isn't a public method but I wanted to unit test it to track - // down a bug - extern uint64_t bitmask(int numBits); - uint64_t result = bitmask(32); - fail_if(result != 0xffffffff); -} -END_TEST - -START_TEST (test_one_bit_not_swapped) -{ - uint64_t data = 0x80; - uint64_t result = getBitField(data, 0, 1, false); - fail_if(result == 1); -} -END_TEST - -START_TEST (test_one_bit) -{ - uint64_t data = 0x8000000000000000; - uint64_t result = getBitField(data, 0, 1, false); - fail_unless(result == 0x1, - "First bit in 0x%llx was 0x%llx instead of 0x1", data, result); -} -END_TEST - -START_TEST (test_32_bit_parse) -{ - uint64_t data = 0x0402574d555a0401; - uint64_t result = getBitField(data, 16, 32, false); - uint64_t expectedValue = 0x574d555a; - fail_unless(result == expectedValue, - "Field retrieved in 0x%llx was 0x%llx instead of 0x%llx", data, - result, expectedValue); -} -END_TEST - -START_TEST (test_16_bit_parse) -{ - uint64_t data = 0xF34DFCFF00000000; - uint64_t result = getBitField(data, 16, 16, false); - uint64_t expectedValue = 0xFCFF; - fail_unless(result == expectedValue, - "Field retrieved in 0x%llx was 0x%llx instead of 0x%llx", data, - result, expectedValue); -} -END_TEST - -START_TEST (test_one_byte) -{ - uint64_t data = 0xFA00000000000000; - uint64_t result = getBitField(data, 0, 4, false); - fail_unless(result == 0xF, - "First 4 bits in 0x%llx was 0x%llx instead of 0xF", data, result); - result = getBitField(data, 4, 4, false); - fail_unless(result == 0xA, - "First 4 bits in 0x%llx was 0x%llx instead of 0xA", data, result); - result = getBitField(data, 0, 8, false); - fail_unless(result == 0xFA, - "All bits in 0x%llx were 0x%llx instead of 0x%llx", data, result, data); -} -END_TEST - -START_TEST (test_multi_byte) -{ - uint64_t data = 0x12FA000000000000; - uint64_t result = getBitField(data, 0, 4, false); - fail_unless(result == 0x1, - "First 4 bits in 0x%llx was 0x%llx instead of 0xF", (data >> 60) & 0xF, - result); - result = getBitField(data, 4, 4, false); - fail_unless(result == 0x2, - "Second 4 bits in 0x%llx was 0x%llx instead of 0xA", (data >> 56) & 0xF, - result); - result = getBitField(data, 8, 4, false); - fail_unless(result == 0xF, - "First 4 bits in 0x%llx was 0x%llx instead of 0x1", (data >> 52) & 0xF, - result); - result = getBitField(data, 12, 4, false); - fail_unless(result == 0xA, - "Second 4 bits in 0x%llx was 0x%llx instead of 0x2", (data >> 48) % 0xF, - result); -} -END_TEST - -START_TEST (test_get_multi_byte) -{ - uint64_t data = 0x12FA000000000000; - uint64_t result = getBitField(data, 0, 9, false); - ck_assert_int_eq(result, 0x25); -} -END_TEST - -START_TEST (test_get_off_byte_boundary) -{ - uint64_t data = 0x000012FA00000000; - uint64_t result = getBitField(data, 12, 8, false); - ck_assert_int_eq(result, 0x01); -} END_TEST - -START_TEST (test_set_field) -{ - uint64_t data = 0; - setBitField(&data, 1, 0, 1); - uint64_t result = getBitField(data, 0, 1, false); - ck_assert_int_eq(result, 0x1); - data = 0; - setBitField(&data, 1, 1, 1); - result = getBitField(data, 1, 1, false); - ck_assert_int_eq(result, 0x1); - - data = 0; - setBitField(&data, 0xf, 3, 4); - result = getBitField(data, 3, 4, false); - ck_assert_int_eq(result, 0xf); -} -END_TEST - -START_TEST (test_set_doesnt_clobber_existing_data) -{ - uint64_t data = 0xFFFC4DF300000000; - setBitField(&data, 0x4fc8, 16, 16); - uint64_t result = getBitField(data, 16, 16, false); - fail_unless(result == 0x4fc8, - "Field retrieved in 0x%llx was 0x%llx instead of 0x%x", data, result, - 0xc84f); - - data = 0x8000000000000000; - setBitField(&data, 1, 21, 1); - fail_unless(data == 0x8000040000000000LLU, - "Expected combined value 0x8000040000000000 but got 0x%llx%llx", - data >> 32, data); -} -END_TEST - -START_TEST (test_set_off_byte_boundary) -{ - uint64_t data = 0xFFFC4DF300000000; - setBitField(&data, 0x12, 12, 8); - uint64_t result = getBitField(data, 12, 12, false); - ck_assert_int_eq(result,0x12d); -} -END_TEST - -START_TEST (test_set_odd_number_of_bits) -{ - uint64_t data = 0xFFFC4DF300000000LLU; - setBitField(&data, 0x12, 11, 5); - uint64_t result = getBitField(data, 11, 5, false); - fail_unless(result == 0x12, - "Field set in 0x%llx%llx%llx%llx was 0x%llx instead of 0x%llx", data, result, - 0x12); - - data = 0xFFFC4DF300000000LLU; - setBitField(&data, 0x2, 11, 5); - result = getBitField(data, 11, 5, false); - fail_unless(result == 0x2, - "Field set in 0x%llx%llx%llx%llx was 0x%llx instead of 0x%llx", data, result, - 0x2); -} -END_TEST - -START_TEST(test_nth_byte) -{ - uint64_t data = 0x00000000F34DFCFF; - uint8_t result = nthByte(data, 0); - uint8_t expected = 0x0; - ck_assert_int_eq(result, expected); - - result = nthByte(data, 4); - expected = 0xF3; - ck_assert_int_eq(result, expected); - - result = nthByte(data, 5); - expected = 0x4D; - ck_assert_int_eq(result, expected); - - result = nthByte(data, 6); - expected = 0xFC; - ck_assert_int_eq(result, expected); - - result = nthByte(data, 7); - expected = 0xFF; - ck_assert_int_eq(result, expected); -} -END_TEST - START_TEST (test_get_byte) { uint8_t data[4] = {0x12, 0x34, 0x56, 0x78}; @@ -243,20 +55,6 @@ END_TEST Suite* bitfieldSuite(void) { Suite* s = suite_create("bitfield"); TCase *tc_core = tcase_create("core"); - tcase_add_test(tc_core, test_large_bitmask); - tcase_add_test(tc_core, test_one_bit); - tcase_add_test(tc_core, test_one_bit_not_swapped); - tcase_add_test(tc_core, test_one_byte); - tcase_add_test(tc_core, test_16_bit_parse); - tcase_add_test(tc_core, test_32_bit_parse); - tcase_add_test(tc_core, test_multi_byte); - tcase_add_test(tc_core, test_get_multi_byte); - tcase_add_test(tc_core, test_get_off_byte_boundary); - tcase_add_test(tc_core, test_set_field); - tcase_add_test(tc_core, test_set_doesnt_clobber_existing_data); - tcase_add_test(tc_core, test_set_off_byte_boundary); - tcase_add_test(tc_core, test_set_odd_number_of_bits); - tcase_add_test(tc_core, test_nth_byte); tcase_add_test(tc_core, test_get_byte); tcase_add_test(tc_core, test_get_nibble); tcase_add_test(tc_core, test_get_bits); -- 2.16.6