Wrote basic makefile, wrote tests, and then fixed them
This commit is contained in:
parent
7adae0da7c
commit
faab7b7cf8
11 changed files with 137 additions and 11 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,2 +1,4 @@
|
|||
*.o
|
||||
*~
|
||||
*.a
|
||||
src/test_suite
|
||||
|
|
|
|||
14
common.mk
Normal file
14
common.mk
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
CFLAGS := $(shell pkg-config --cflags glib-2.0)
|
||||
LDFLAGS := $(shell pkg-config --libs glib-2.0)
|
||||
CC := gcc
|
||||
|
||||
CFLAGS += -DINCLUDE_TESTS
|
||||
|
||||
.SUFFIX:
|
||||
|
||||
%.a:
|
||||
-rm -f $@
|
||||
ar crv $@ $^
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
CFLAGS := $(shell pkg-config --cflags glib-2.0)
|
||||
LDFLAGS := $(shell pkg-config --libs glib-2.0)
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
include ../config.mk
|
||||
include ../common.mk
|
||||
|
||||
all: allocator.o
|
||||
|
||||
%.o: %.c
|
||||
gcc $(CFLAGS) -c -o $@ $^
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
typedef struct arena* arena_t; // hidden implementation
|
||||
|
||||
arena_t new_arena(size_t block_size); // pass 0 for default...
|
||||
void* arena_malloc(arena_t arena, size_t count); // TODO: needs the malloc attribute
|
||||
void* arena_malloc(arena_t arena, size_t count) __attribute__(( malloc, alloc_size(2) ));
|
||||
void delete_arena(arena_t arena);
|
||||
|
||||
|
||||
|
|
|
|||
10
src/Makefile
Normal file
10
src/Makefile
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
-include ../common.mk
|
||||
|
||||
all: libhammer.a test_suite
|
||||
|
||||
test_suite: test_suite.o libhammer.a
|
||||
$(CC) $(LDFLAGS) -o $@ $^
|
||||
|
||||
libhammer.a: bitreader.o
|
||||
|
||||
bitreader.o: test_suite.h
|
||||
|
|
@ -1,14 +1,17 @@
|
|||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "internal.h"
|
||||
#include "hammer.h"
|
||||
#include "test_suite.h"
|
||||
|
||||
#define LSB(range) (0:range)
|
||||
#define MSB(range) (1:range)
|
||||
#define LDB(range,i) (((i)>>LSB(range))&((1<<(MSB(range)-LSB(range)+1))-1))
|
||||
|
||||
long long read_bits(parse_state_t* state, int count) {
|
||||
long long read_bits(input_stream_t* state, int count, char signed_p) {
|
||||
long long out = 0;
|
||||
int offset = 0;
|
||||
long long msb = (!!signed_p) << (count - 1); // 0 if unsigned, else 1 << (nbits - 1)
|
||||
while (count) {
|
||||
int segment, segment_len;
|
||||
// Read a segment...
|
||||
|
|
@ -45,5 +48,65 @@ long long read_bits(parse_state_t* state, int count) {
|
|||
}
|
||||
count -= segment_len;
|
||||
}
|
||||
return out;
|
||||
return (out ^ msb) - msb; // perform sign extension
|
||||
}
|
||||
|
||||
#ifdef INCLUDE_TESTS
|
||||
|
||||
#define MK_INPUT_STREAM(buf,len,endianness_) \
|
||||
{ \
|
||||
.input = buf, \
|
||||
.length = len, \
|
||||
.index = 0, \
|
||||
.bit_offset = (((endianness_) & BIT_BIG_ENDIAN) ? 8 : 0), \
|
||||
.endianness = endianness_ \
|
||||
}
|
||||
|
||||
static void test_bitreader_be(void) {
|
||||
input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN);
|
||||
g_check_cmpint(read_bits(&is, 3, false), ==, 0x03);
|
||||
g_check_cmpint(read_bits(&is, 8, false), ==, 0x52);
|
||||
g_check_cmpint(read_bits(&is, 5, false), ==, 0x1A);
|
||||
}
|
||||
static void test_bitreader_le(void) {
|
||||
input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN);
|
||||
g_check_cmpint(read_bits(&is, 3, false), ==, 0x02);
|
||||
g_check_cmpint(read_bits(&is, 8, false), ==, 0x4D);
|
||||
g_check_cmpint(read_bits(&is, 5, false), ==, 0x0B);
|
||||
}
|
||||
|
||||
static void test_largebits_be(void) {
|
||||
input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN);
|
||||
g_check_cmpint(read_bits(&is, 11, false), ==, 0x352);
|
||||
g_check_cmpint(read_bits(&is, 5, false), ==, 0x1A);
|
||||
}
|
||||
|
||||
static void test_largebits_le(void) {
|
||||
input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN);
|
||||
g_check_cmpint(read_bits(&is, 11, false), ==, 0x26A);
|
||||
g_check_cmpint(read_bits(&is, 5, false), ==, 0x0B);
|
||||
}
|
||||
|
||||
static void test_offset_largebits_be(void) {
|
||||
input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_BIG_ENDIAN | BYTE_BIG_ENDIAN);
|
||||
g_check_cmpint(read_bits(&is, 5, false), ==, 0xD);
|
||||
g_check_cmpint(read_bits(&is, 11, false), ==, 0x25A);
|
||||
}
|
||||
|
||||
static void test_offset_largebits_le(void) {
|
||||
input_stream_t is = MK_INPUT_STREAM("\x6A\x5A", 2, BIT_LITTLE_ENDIAN | BYTE_LITTLE_ENDIAN);
|
||||
g_check_cmpint(read_bits(&is, 5, false), ==, 0xA);
|
||||
g_check_cmpint(read_bits(&is, 11, false), ==, 0x2D3);
|
||||
}
|
||||
|
||||
|
||||
void register_bitreader_tests(void) {
|
||||
g_test_add_func("/core/bitreader/be", test_bitreader_be);
|
||||
g_test_add_func("/core/bitreader/le", test_bitreader_le);
|
||||
g_test_add_func("/core/bitreader/largebits-be", test_largebits_be);
|
||||
g_test_add_func("/core/bitreader/largebits-le", test_largebits_le);
|
||||
g_test_add_func("/core/bitreader/offset-largebits-be", test_offset_largebits_be);
|
||||
g_test_add_func("/core/bitreader/offset-largebits-le", test_offset_largebits_le);
|
||||
}
|
||||
|
||||
#endif // #ifdef INCLUDE_TESTS
|
||||
|
|
|
|||
11
src/hammer.h
11
src/hammer.h
|
|
@ -37,14 +37,21 @@
|
|||
*/
|
||||
#define BYTE_BIG_ENDIAN 0x1
|
||||
#define BIT_BIG_ENDIAN 0x2
|
||||
#define BIT_LITTLE_ENDIAN 0x0
|
||||
#define BYTE_LITTLE_ENDIAN 0x0
|
||||
|
||||
typedef struct parse_state {
|
||||
typedef struct input_stream {
|
||||
// This should be considered to be a really big value type.
|
||||
const uint8_t *input;
|
||||
GHashTable *cache;
|
||||
size_t index;
|
||||
size_t length;
|
||||
char bit_offset;
|
||||
char endianness;
|
||||
} input_stream_t;
|
||||
|
||||
typedef struct parse_state {
|
||||
GHashTable *cache;
|
||||
input_stream_t input_stream;
|
||||
} parse_state_t;
|
||||
|
||||
typedef struct parse_result {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
#define HAMMER_INTERNAL__H
|
||||
#include "hammer.h"
|
||||
|
||||
long long read_bits(parse_state_t* state, int count);
|
||||
#define false 0
|
||||
#define true 1
|
||||
|
||||
long long read_bits(input_stream_t* state, int count, char signed_p);
|
||||
|
||||
#endif // #ifndef HAMMER_INTERNAL__H
|
||||
|
|
|
|||
14
src/test_suite.c
Normal file
14
src/test_suite.c
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include "hammer.h"
|
||||
#include "test_suite.h"
|
||||
|
||||
extern void register_bitreader_tests();
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
g_test_init(&argc, &argv, NULL);
|
||||
|
||||
// register various test suites...
|
||||
register_bitreader_tests();
|
||||
|
||||
g_test_run();
|
||||
}
|
||||
|
||||
17
src/test_suite.h
Normal file
17
src/test_suite.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
#ifndef HAMMER_TEST_SUITE__H
|
||||
#define HAMMER_TEST_SUITE__H
|
||||
|
||||
// Equivalent to g_assert_*, but not using g_assert...
|
||||
#define g_check_cmpint(n1, op, n2) { \
|
||||
typeof (n1) _n1 = (n1); \
|
||||
typeof (n2) _n2 = (n2); \
|
||||
if (!(_n1 op _n2)) { \
|
||||
g_test_message("Check failed: (%s): (%d %s %d)", \
|
||||
#n1 " " #op " " #n2, \
|
||||
_n1, #op, _n2); \
|
||||
g_test_fail(); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#endif // #ifndef HAMMER_TEST_SUITE__H
|
||||
Loading…
Add table
Add a link
Reference in a new issue