Skip to content
Snippets Groups Projects
Commit faab7b7c authored by Dan Hirsch's avatar Dan Hirsch
Browse files

Wrote basic makefile, wrote tests, and then fixed them

parent 7adae0da
No related branches found
No related tags found
No related merge requests found
*.o *.o
*~ *~
*.a
src/test_suite
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 $@ $<
\ No newline at end of file
CFLAGS := $(shell pkg-config --cflags glib-2.0)
LDFLAGS := $(shell pkg-config --libs glib-2.0)
\ No newline at end of file
include ../config.mk include ../common.mk
all: allocator.o all: allocator.o
%.o: %.c
gcc $(CFLAGS) -c -o $@ $^
\ No newline at end of file
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
typedef struct arena* arena_t; // hidden implementation typedef struct arena* arena_t; // hidden implementation
arena_t new_arena(size_t block_size); // pass 0 for default... 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); void delete_arena(arena_t arena);
......
-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
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include "internal.h" #include "internal.h"
#include "hammer.h" #include "hammer.h"
#include "test_suite.h"
#define LSB(range) (0:range) #define LSB(range) (0:range)
#define MSB(range) (1:range) #define MSB(range) (1:range)
#define LDB(range,i) (((i)>>LSB(range))&((1<<(MSB(range)-LSB(range)+1))-1)) #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; long long out = 0;
int offset = 0; int offset = 0;
long long msb = (!!signed_p) << (count - 1); // 0 if unsigned, else 1 << (nbits - 1)
while (count) { while (count) {
int segment, segment_len; int segment, segment_len;
// Read a segment... // Read a segment...
...@@ -45,5 +48,65 @@ long long read_bits(parse_state_t* state, int count) { ...@@ -45,5 +48,65 @@ long long read_bits(parse_state_t* state, int count) {
} }
count -= segment_len; 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
...@@ -37,14 +37,21 @@ ...@@ -37,14 +37,21 @@
*/ */
#define BYTE_BIG_ENDIAN 0x1 #define BYTE_BIG_ENDIAN 0x1
#define BIT_BIG_ENDIAN 0x2 #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; const uint8_t *input;
GHashTable *cache;
size_t index; size_t index;
size_t length; size_t length;
char bit_offset; char bit_offset;
char endianness; char endianness;
} input_stream_t;
typedef struct parse_state {
GHashTable *cache;
input_stream_t input_stream;
} parse_state_t; } parse_state_t;
typedef struct parse_result { typedef struct parse_result {
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
#define HAMMER_INTERNAL__H #define HAMMER_INTERNAL__H
#include "hammer.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 #endif // #ifndef HAMMER_INTERNAL__H
#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();
}
#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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment