Remove old deprecated dqn lib

This commit is contained in:
doyle 2020-04-15 00:42:18 +10:00
parent 21104f85d5
commit 2f681515f6
14 changed files with 0 additions and 25470 deletions

View File

@ -1,38 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="DqnArray&lt;*&gt;">
<DisplayString>{{len={len}/{max}}}</DisplayString>
<Expand>
<Item Name="[len]">len</Item>
<Item Name="[max]">max</Item>
<ArrayItems>
<Size>len</Size>
<ValuePointer>data</ValuePointer>
</ArrayItems>
</Expand>
</Type>
<Type Name="DqnMemStack::Block">
<DisplayString>{{used={head-tail}/{size} prev_block={prev_block}}}</DisplayString>
</Type>
<Type Name="DqnSlice&lt;*&gt;">
<DisplayString>{len={len} data={data,[len]}}</DisplayString>
<StringView>data,s</StringView>
</Type>
<Type Name="DqnBuffer&lt;*&gt;">
<DisplayString>{len={len} data={data,[len]}}</DisplayString>
<StringView>data,s</StringView>
</Type>
<Type Name="DqnFixedString&lt;*&gt;">
<DisplayString>{{len={len} {str,s}}}</DisplayString>
<StringView>str,s</StringView>
</Type>
<Type Name="DqnString">
<DisplayString>{{len={len}/{max} {str,s}}}</DisplayString>
<StringView>str,s</StringView>
</Type>
</AutoVisualizer>

View File

@ -1,77 +0,0 @@
void DqnFixedString_Test()
{
LOG_HEADER();
{
DqnFixedString<512> str = DQN_BUFFER_STR_LIT("hello world");
DQN_ASSERT(DqnStr_Cmp(str.str, "hello world") == 0);
Log(Status::Ok, "Copy constructor DqnSlice<char>");
}
{
DqnFixedString<512> zero = {};
DqnFixedString<512> str = DQN_BUFFER_STR_LIT("hello world");
str = zero;
DQN_ASSERT(str.len == 0 && str.str[0] == 0);
DqnSlice<char const> helloSlice = DQN_BUFFER_STR_LIT("hello");
str = helloSlice;
DQN_ASSERT(DqnStr_Cmp(str.str, "hello") == 0);
Log(Status::Ok, "Copy constructor (DqnFixedString<>)");
}
{
DqnFixedString<512> str = DQN_BUFFER_STR_LIT("hello world");
DQN_ASSERT(str.Sprintf("hello %s", "sailor"));
DQN_ASSERTM(DqnStr_Cmp(str.str, "hello sailor") == 0, "Result: %s", str.str);
Log(Status::Ok, "Sprintf");
}
{
{
DqnFixedString<512> str = DQN_BUFFER_STR_LIT("hello world");
DQN_ASSERT(str.Sprintf("hello %s", "sailor"));
str += DQN_BUFFER_STR_LIT(".end");
DQN_ASSERTM(DqnStr_Cmp(str.str, "hello sailor.end") == 0, "Result: %s", str.str);
}
{
DqnFixedString<512> str = DQN_BUFFER_STR_LIT("hello world");
DQN_ASSERT(str.Sprintf("hello %s", "sailor"));
DQN_ASSERT(str.SprintfAppend(" %d, %d", 100, 200));
DQN_ASSERT(DqnStr_Cmp(str.str, "hello sailor 100, 200") == 0);
}
Log(Status::Ok, "Concatenation, operator +=, SprintfAppend");
}
{
DqnFixedString<512> str;
str = "hello big world";
DQN_ASSERT(DqnStr_Cmp(str.str, "hello big world") == 0);
str = DqnFixedString<512>("goodbye", DQN_CHAR_COUNT("goodbye"));
DQN_ASSERT(DqnStr_Cmp(str.str, "goodbye") == 0);
Log(Status::Ok, "Copy constructor (char const *str, int len)");
}
{
DqnFixedString<512> str = DQN_BUFFER_STR_LIT("hello world");
DQN_ASSERT(str.Sprintf("hello %s", "sailor"));
str = str + " end" + DQN_BUFFER_STR_LIT(" of");
DQN_ASSERT(DqnStr_Cmp(str.str, "hello sailor end of") == 0);
Log(Status::Ok, "Operator +");
}
{
DqnFixedString<512> str = "localhost";
str.SprintfAppend(":%d", 16832);
str += "/json_rpc";
DQN_ASSERT(str.len == 24 && DqnStr_Cmp("localhost:16832/json_rpc", str.str) == 0);
Log(Status::Ok, "Copy constructor, sprintf, operator +=");
}
}

View File

@ -1,119 +0,0 @@
void DqnJson_Test()
{
LOG_HEADER();
char const json[] =
R"FOO(
{
"result": {
"cumulative_difficulty": 282912831023,
"difficulty": 18293,
"name": "Block",
"array_of_objects": [{
"hash": "83abdc3f",
"time": 102981029381,
}, {
"hash": "12acf73d",
"time": 123761239789,
}],
"time": 3498573485,
"embed_object": {
"proof": "axcbde",
"signature": "l9382kjabmznmx129aslzejs"
}
"bits": [1, 0, 1, 1, 0, 1, 0],
"hex": ["AF", "BE", "0C", "FF"],
"extra": [123],
"serialise": [],
},
}
)FOO";
DqnJson result = DqnJson_Get(DqnSlice<const char>(json, DQN_ARRAY_COUNT(json)), DQN_BUFFER_STR_LIT("result"));
DqnJson cum_difficulty = DqnJson_Get(result, DQN_BUFFER_STR_LIT("cumulative_difficulty"));
DqnJson difficulty = DqnJson_Get(result, DQN_BUFFER_STR_LIT("difficulty"));
DqnJson name = DqnJson_Get(result, DQN_BUFFER_STR_LIT("name"));
DqnJson array_of_objects = DqnJson_Get(result, DQN_BUFFER_STR_LIT("array_of_objects"));
DqnJson time = DqnJson_Get(result, DQN_BUFFER_STR_LIT("time"));
DqnJson embed_object = DqnJson_Get(result, DQN_BUFFER_STR_LIT("embed_object"));
DqnJson bits = DqnJson_Get(result, DQN_BUFFER_STR_LIT("bits"));
DqnJson hex = DqnJson_Get(result, DQN_BUFFER_STR_LIT("hex"));
DqnJson extra = DqnJson_Get(result, DQN_BUFFER_STR_LIT("extra"));
DqnJson serialise = DqnJson_Get(result, DQN_BUFFER_STR_LIT("serialise"));
DQN_ASSERT(DQN_BUFFER_STRCMP(cum_difficulty.value, DQN_BUFFER_STR_LIT("282912831023"), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(difficulty.value, DQN_BUFFER_STR_LIT("18293"), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(name.value, DQN_BUFFER_STR_LIT("\"Block\""), Dqn::IgnoreCase::No));
{
DQN_ASSERT(array_of_objects.IsArray() && array_of_objects.num_entries == 2);
isize count = 0;
while(DqnJson it = DqnJson_GetNextArrayItem(&array_of_objects))
{
DqnJson hash = DqnJson_Get(it, DQN_BUFFER_STR_LIT("hash"));
DqnJson time2 = DqnJson_Get(it, DQN_BUFFER_STR_LIT("time"));
if (count == 0)
{
DQN_ASSERT(DQN_BUFFER_STRCMP(hash.value, DQN_BUFFER_STR_LIT("\"83abdc3f\""), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(time2.value, DQN_BUFFER_STR_LIT("102981029381"), Dqn::IgnoreCase::No));
}
else
{
DQN_ASSERT(DQN_BUFFER_STRCMP(hash.value, DQN_BUFFER_STR_LIT("\"12acf73d\""), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(time2.value, DQN_BUFFER_STR_LIT("123761239789"), Dqn::IgnoreCase::No));
}
++count;
}
}
{
DqnJson proof = DqnJson_Get(embed_object, DQN_BUFFER_STR_LIT("proof"));
DqnJson signature = DqnJson_Get(embed_object, DQN_BUFFER_STR_LIT("signature"));
DQN_ASSERT(DQN_BUFFER_STRCMP(proof.value, DQN_BUFFER_STR_LIT("\"axcbde\""), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(signature.value, DQN_BUFFER_STR_LIT("\"l9382kjabmznmx129aslzejs\""), Dqn::IgnoreCase::No));
}
DQN_ASSERT(DQN_BUFFER_STRCMP(time.value, DQN_BUFFER_STR_LIT("3498573485"), Dqn::IgnoreCase::No));
{
DQN_ASSERT(bits.IsArray() && bits.num_entries == 7);
DqnJson bits_array[7];
isize bitsIndex = 0;
while(DqnJson it = DqnJson_GetNextArrayItem(&bits))
bits_array[bitsIndex++] = it;
DQN_ASSERT(bitsIndex == DQN_ARRAY_COUNT(bits_array));
DQN_ASSERT(DQN_BUFFER_STRCMP(bits_array[0].value, DQN_BUFFER_STR_LIT("1"), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(bits_array[1].value, DQN_BUFFER_STR_LIT("0"), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(bits_array[2].value, DQN_BUFFER_STR_LIT("1"), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(bits_array[3].value, DQN_BUFFER_STR_LIT("1"), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(bits_array[4].value, DQN_BUFFER_STR_LIT("0"), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(bits_array[5].value, DQN_BUFFER_STR_LIT("1"), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(bits_array[6].value, DQN_BUFFER_STR_LIT("0"), Dqn::IgnoreCase::No));
}
{
DQN_ASSERT(hex.IsArray() && hex.num_entries == 4);
DqnJson hex_array[4];
isize hex_index = 0;
while(DqnJson it = DqnJson_GetNextArrayItem(&hex))
hex_array[hex_index++] = it;
DQN_ASSERT(hex_index == DQN_ARRAY_COUNT(hex_array));
DQN_ASSERT(DQN_BUFFER_STRCMP(hex_array[0].value, DQN_BUFFER_STR_LIT("\"AF\""), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(hex_array[1].value, DQN_BUFFER_STR_LIT("\"BE\""), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(hex_array[2].value, DQN_BUFFER_STR_LIT("\"0C\""), Dqn::IgnoreCase::No));
DQN_ASSERT(DQN_BUFFER_STRCMP(hex_array[3].value, DQN_BUFFER_STR_LIT("\"FF\""), Dqn::IgnoreCase::No));
}
{
DQN_ASSERT(extra.IsArray() && extra.num_entries == 1);
while(DqnJson it = DqnJson_GetNextArrayItem(&extra))
{
DQN_ASSERT(DQN_BUFFER_STRCMP(it.value, DQN_BUFFER_STR_LIT("123"), Dqn::IgnoreCase::No));
}
}
Log(Status::Ok, "DqnJson sample structure parsed");
}

View File

@ -1,520 +0,0 @@
FILE_SCOPE void DqnMemStack_Test()
{
LOG_HEADER();
// Check Alignment
if (1)
{
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, 0, DqnMemTracker::Flag::Simple);
i32 const ALIGN64 = 64;
i32 const ALIGN16 = 16;
i32 const ALIGN4 = 4;
DqnMemStack::PushType push_type = DqnMemStack::PushType::Head;
if (1)
{
u8 *result1 = (u8 *)stack.Push_(2, push_type, ALIGN4);
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN4);
DQN_ASSERT(result1 == result2);
stack.Pop(result1);
DQN_ASSERT(stack.block->head == stack.block->memory);
}
if (1)
{
u8 *result1 = (u8 *)stack.Push_(120, push_type, ALIGN16);
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN16);
DQN_ASSERT(result1 == result2);
stack.Pop(result1);
DQN_ASSERT(stack.block->head == stack.block->memory);
}
if (1)
{
u8 *result1 = (u8 *)stack.Push_(12, push_type, ALIGN64);
u8 *result2 = (u8 *)DQN_ALIGN_POW_N(result1, ALIGN64);
DQN_ASSERT(result1 == result2);
stack.Pop(result1);
DQN_ASSERT(stack.block->head == stack.block->memory);
}
stack.Free();
Log(Status::Ok, "Check allocated alignment to 4, 16, 64");
}
// Check Non-Expandable
if (1)
{
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, DqnMemStack::Flag::NonExpandable);
auto *result1 = stack.Push_(DQN_MEGABYTE(2));
DQN_ASSERT(result1 == nullptr);
DQN_ASSERT(stack.block->prev_block == nullptr);
stack.Free();
Log(Status::Ok, "Check non-expandable flag prevents expansion.");
}
// Check Expansion
if (1)
{
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes);
auto *old_block = stack.block;
DQN_ASSERT(old_block);
DQN_ASSERT(old_block->size == DQN_MEGABYTE(1));
DQN_ASSERT(old_block->head == old_block->head);
DQN_ASSERT(old_block->tail == old_block->tail);
DQN_ASSERT(old_block->prev_block == nullptr);
auto *result1 = stack.Push_(DQN_MEGABYTE(2));
DQN_ASSERT(result1);
DQN_ASSERT(stack.block->prev_block == old_block);
DQN_ASSERT(stack.block != old_block);
Log(Status::Ok, "Check memory stack allocates additional memory blocks.");
stack.Free();
}
// Temporary Regions
if (1)
{
// Check temporary regions
if (1)
{
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, 0, DqnMemTracker::Flag::Simple);
DqnMemStack::Block *block_to_return_to = stack.block;
auto head_before = block_to_return_to->head;
auto tail_before = block_to_return_to->tail;
if (1)
{
auto mem_guard1 = stack.MemRegionScope();
auto *result2 = stack.Push_(100);
auto *result3 = stack.Push_(100);
auto *result4 = stack.Push_(100);
DQN_ASSERT(result2 && result3 && result4);
DQN_ASSERT(stack.block->head != head_before);
DQN_ASSERT(stack.block->tail == tail_before);
DQN_ASSERT(stack.block->memory == block_to_return_to->memory);
// Force allocation of new block
auto *result5 = stack.Push_(DQN_MEGABYTE(5));
DQN_ASSERT(result5);
DQN_ASSERT(stack.block != block_to_return_to);
DQN_ASSERT(stack.mem_region_count == 1);
}
DQN_ASSERT(stack.block == block_to_return_to);
DQN_ASSERT(stack.block->head == head_before);
DQN_ASSERT(stack.block->tail == tail_before);
stack.Free();
}
// Check temporary regions keep state
if (1)
{
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, 0, DqnMemTracker::Flag::Simple);
DqnMemStack::Block *block_to_return_to = stack.block;
auto head_before = block_to_return_to->head;
auto tail_before = block_to_return_to->tail;
if (1)
{
auto mem_guard1 = stack.MemRegionScope();
auto *result2 = stack.Push_(100);
auto *result3 = stack.Push_(100);
auto *result4 = stack.Push_(100);
DQN_ASSERT(result2 && result3 && result4);
DQN_ASSERT(stack.block->head != head_before);
DQN_ASSERT(stack.block->tail == tail_before);
DQN_ASSERT(stack.block->memory == block_to_return_to->memory);
// Force allocation of new block
auto *result5 = stack.Push_(DQN_MEGABYTE(5));
DQN_ASSERT(result5);
DQN_ASSERT(stack.block != block_to_return_to);
DQN_ASSERT(stack.mem_region_count == 1);
stack.MemRegionSave(&mem_guard1);
}
DQN_ASSERT(stack.block != block_to_return_to);
DQN_ASSERT(stack.block->prev_block == block_to_return_to);
DQN_ASSERT(stack.mem_region_count == 0);
stack.Free();
}
// Check temporary regions with tail and head pushes
if (1)
{
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, 0, DqnMemTracker::Flag::Simple);
auto *pop1 = stack.Push_(222);
auto *pop2 = stack.Push_(333, DqnMemStack::PushType::Tail);
DqnMemStack::Block *block_to_return_to = stack.block;
auto head_before = block_to_return_to->head;
auto tail_before = block_to_return_to->tail;
if (1)
{
auto mem_guard1 = stack.MemRegionScope();
auto *result2 = stack.Push_(100);
auto *result3 = stack.Push_(100, DqnMemStack::PushType::Tail);
auto *result4 = stack.Push_(100);
auto *result5 = stack.Push_(100, DqnMemStack::PushType::Tail);
DQN_ASSERT(result2 && result3 && result4 && result5);
DQN_ASSERT(result3 > result5);
DQN_ASSERT(result2 < result4);
DQN_ASSERT(stack.block->head > head_before && stack.block->head < stack.block->tail);
DQN_ASSERT(stack.block->tail >= stack.block->head && stack.block->tail < (stack.block->memory + stack.block->size));
DQN_ASSERT(stack.block->memory == block_to_return_to->memory);
// Force allocation of new block
auto *result6 = stack.Push_(DQN_MEGABYTE(5));
DQN_ASSERT(result6);
DQN_ASSERT(stack.block != block_to_return_to);
DQN_ASSERT(stack.mem_region_count == 1);
}
DQN_ASSERT(stack.block == block_to_return_to);
DQN_ASSERT(stack.block->head == head_before);
DQN_ASSERT(stack.block->tail == tail_before);
stack.Pop(pop1);
stack.Pop(pop2);
DQN_ASSERT(stack.block->head == stack.block->memory);
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
stack.Free();
}
Log(Status::Ok, "Temporary regions revert state and save state");
}
// Check Fixed Mem Init
if (1)
{
// Check success
if (1)
{
isize const buf_size = sizeof(DqnMemStack::Block) * 5;
char buf[buf_size] = {};
auto stack = DqnMemStack(&buf, buf_size, Dqn::ZeroMem::No);
DQN_ASSERT(stack.block);
DQN_ASSERT(stack.block->prev_block == false);
DQN_ASSERT(stack.mem_region_count == 0);
DQN_ASSERT(stack.flags == DqnMemStack::Flag::NonExpandable);
auto *result1 = stack.Push_(32);
DQN_ASSERT(result1);
stack.Pop(result1);
auto *result2 = stack.Push_(buf_size * 2);
DQN_ASSERT(result2 == nullptr);
DQN_ASSERT(stack.block);
DQN_ASSERT(stack.block->prev_block == false);
DQN_ASSERT(stack.mem_region_count == 0);
DQN_ASSERT(stack.flags == DqnMemStack::Flag::NonExpandable);
stack.Free();
}
Log(Status::Ok, "Checked fixed mem initialisation");
}
// Check Freeing Blocks
if (1)
{
usize size = 32;
usize additional_size = DqnMemStack::MINIMUM_BLOCK_SIZE;
auto stack = DqnMemStack(size, Dqn::ZeroMem::Yes, 0);
auto *block1 = stack.block;
size += additional_size;
auto *result1 = stack.Push_(size);
auto *block2 = stack.block;
size += additional_size;
auto *result2 = stack.Push_(size);
auto *block3 = stack.block;
size += additional_size;
auto *result3 = stack.Push_(size);
auto *block4 = stack.block;
size += additional_size;
auto *result4 = stack.Push_(size);
auto *block5 = stack.block;
DQN_ASSERT(result1 && result2 && result3 && result4);
DQN_ASSERT(block1 && block2 && block3 && block4 && block5);
DQN_ASSERT(block5->prev_block == block4);
DQN_ASSERT(block4->prev_block == block3);
DQN_ASSERT(block3->prev_block == block2);
DQN_ASSERT(block2->prev_block == block1);
DQN_ASSERT(block1->prev_block == nullptr);
DQN_ASSERT(stack.FreeBlock(block4));
DQN_ASSERT(stack.block == block5);
DQN_ASSERT(block5->prev_block == block3);
DQN_ASSERT(block3->prev_block == block2);
DQN_ASSERT(block2->prev_block == block1);
DQN_ASSERT(block1->prev_block == nullptr);
DQN_ASSERT(stack.FreeBlock(block5));
DQN_ASSERT(stack.block == block3);
DQN_ASSERT(block3->prev_block == block2);
DQN_ASSERT(block2->prev_block == block1);
DQN_ASSERT(block1->prev_block == nullptr);
stack.Free();
DQN_ASSERT(stack.block == nullptr);
Log(Status::Ok, "Check freeing arbitrary blocks and freeing");
}
// Check bounds guard places magic values
if (1)
{
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, 0, DqnMemTracker::Flag::Simple);
char *result = static_cast<char *>(stack.Push_(64));
// TODO(doyle): check head and tail are adjacent to the bounds of the allocation
u32 *head = stack.tracker.PtrToHeadGuard(result);
u32 *tail = stack.tracker.PtrToTailGuard(result);
DQN_ASSERT(*head == DqnMemTracker::HEAD_GUARD_VALUE);
DQN_ASSERT(*tail == DqnMemTracker::TAIL_GUARD_VALUE);
stack.Free();
Log(Status::Ok, "Bounds guards are placed adjacent and have magic values.");
}
if (1)
{
// Push_ to tail and head
if (1)
{
DqnMemStack stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, 0, DqnMemTracker::Flag::Simple);
auto *result1 = stack.Push_(100);
auto *result2 = stack.Push_(100, DqnMemStack::PushType::Tail);
auto *head_before = stack.block->head;
auto *tail_before = stack.block->tail;
DQN_ASSERT(result2 && result1);
DQN_ASSERT(result2 != result1 && result1 < result2);
stack.Pop(result2);
DQN_ASSERT(head_before == stack.block->head)
DQN_ASSERT(tail_before != stack.block->tail)
stack.Pop(result1);
DQN_ASSERT(stack.block->prev_block == false);
DQN_ASSERT(stack.block->head == stack.block->memory);
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
stack.Free();
Log(Status::Ok, "Push_, pop to tail and head.");
}
// Expansion with tail
if (1)
{
// Push_ too much to tail causes expansion
if (1)
{
DqnMemStack stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, 0, DqnMemTracker::Flag::Simple);
auto *result1 = stack.Push_(100);
DQN_ASSERT(stack.block->prev_block == nullptr);
DQN_ASSERT(stack.block->head > stack.block->memory && stack.block->head < stack.block->tail);
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
auto *block_before = stack.block;
auto *result2 = stack.Push_(DQN_MEGABYTE(1), DqnMemStack::PushType::Tail);
DQN_ASSERT(result2 && result1);
DQN_ASSERT(result2 != result1);
DQN_ASSERT(stack.block->prev_block == block_before);
DQN_ASSERT(stack.block != block_before);
DQN_ASSERT(stack.block->head == stack.block->memory);
DQN_ASSERT(stack.block->tail < stack.block->memory + stack.block->size &&
stack.block->tail >= stack.block->head);
stack.Pop(result2);
DQN_ASSERT(block_before == stack.block);
stack.Pop(result1);
DQN_ASSERT(block_before == stack.block);
stack.Free();
}
// Push_ too much to tail fails to expand when non expandable
if (1)
{
DqnMemStack stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, DqnMemStack::Flag::NonExpandable);
auto *result1 = stack.Push_(100);
DQN_ASSERT(stack.block->prev_block == nullptr);
DQN_ASSERT(stack.block->head != stack.block->memory);
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
auto *block_before = stack.block;
auto *result2 = stack.Push_(DQN_MEGABYTE(1), DqnMemStack::PushType::Tail);
DQN_ASSERT(result2 == nullptr);
DQN_ASSERT(stack.block->prev_block == nullptr);
DQN_ASSERT(stack.block == block_before);
DQN_ASSERT(stack.block->head > stack.block->memory && stack.block->head < stack.block->tail);
DQN_ASSERT(stack.block->tail == stack.block->memory + stack.block->size);
stack.Pop(result2);
DQN_ASSERT(block_before == stack.block);
stack.Pop(result1);
DQN_ASSERT(block_before == stack.block);
stack.Free();
}
Log(Status::Ok, "Non-Expanding and expanding stack with tail push.");
}
}
// Check stack allocator mem api callbacks
if (1)
{
#if 0
// Realloc in same block and allow it to grow in place.
if (1)
{
// Using push on head
if (1)
{
DqnMemStack stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, DqnMemStack::Flag::BoundsGuard);
auto *api = &stack.myHeadAPI;
auto *block_before = stack.block;
auto *head_before = stack.block->head;
isize buf_size = 16;
char *buf = (char *)stack.Push_(buf_size);
DqnMem_Set(buf, 'X', buf_size);
for (auto i = 0; i < buf_size; i++) DQN_ASSERT(buf[i] == 'X');
isize old_buf_size = buf_size;
buf_size = 32;
buf = (char *)api->Realloc(buf, old_buf_size, buf_size);
for (auto i = 0; i < old_buf_size; i++) DQN_ASSERT(buf[i] == 'X');
DqnMem_Set(buf, '@', buf_size);
DQN_ASSERT(block_before == stack.block);
DQN_ASSERT(head_before < stack.block->head);
stack.Pop(buf);
DQN_ASSERT(block_before == stack.block);
DQN_ASSERT(head_before == stack.block->head);
DQN_ASSERT(head_before == stack.block->memory);
stack.Free();
}
// Using push on tail
if (1)
{
DqnMemStack stack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, DqnMemStack::Flag::BoundsGuard);
auto *api = &stack.myHeadAPI;
auto *block_before = stack.block;
auto *tail_before = stack.block->tail;
isize buf_size = 16;
char *buf = (char *)stack.Push_(buf_size, DqnMemStack::PushType::Tail);
DqnMem_Set(buf, 'X', buf_size);
for (auto i = 0; i < buf_size; i++) DQN_ASSERT(buf[i] == 'X');
isize old_buf_size = buf_size;
buf_size = 32;
buf = (char *)api->Realloc(buf, old_buf_size, buf_size);
for (auto i = 0; i < old_buf_size; i++) DQN_ASSERT(buf[i] == 'X');
DqnMem_Set(buf, '@', buf_size);
DQN_ASSERT(block_before == stack.block);
DQN_ASSERT(tail_before > stack.block->tail);
stack.Pop(buf);
DQN_ASSERT(block_before == stack.block);
DQN_ASSERT(tail_before == stack.block->tail);
DQN_ASSERT(stack.block->head == stack.block->memory);
stack.Free();
}
Log(Status::Ok, "Allocator MemAPI callback, realloc grow in place");
}
// Realloc in same block and insufficient size and expand
if (1)
{
// Using push on head
if (1)
{
auto stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, DqnMemStack::Flag::BoundsGuard);
auto *api = &stack.myHeadAPI;
auto *block_before = stack.block;
auto *head_before = stack.block->head;
isize buf_size = 16;
char *buf = (char *)stack.Push_(buf_size);
DqnMem_Set(buf, 'X', buf_size);
for (auto i = 0; i < buf_size; i++) DQN_ASSERT(buf[i] == 'X');
isize old_buf_size = buf_size;
buf_size = DQN_MEGABYTE(2);
buf = (char *)api->Realloc(buf, old_buf_size, buf_size);
for (auto i = 0; i < old_buf_size; i++) DQN_ASSERT(buf[i] == 'X');
DqnMem_Set(buf, '@', buf_size);
DQN_ASSERT(block_before == stack.block->prev_block);
stack.Pop(buf);
DQN_ASSERT(block_before == stack.block);
DQN_ASSERT(head_before == stack.block->head);
DQN_ASSERT(head_before == stack.block->memory);
stack.Free();
}
// Using push on tail
if (1)
{
DqnMemStack stack = DqnMemStack(DQN_MEGABYTE(1), Dqn::ZeroMem::Yes, DqnMemStack::Flag::BoundsGuard);
auto *api = &stack.myHeadAPI;
auto *block_before = stack.block;
auto *tail_before = stack.block->tail;
isize buf_size = 16;
char *buf = (char *)stack.Push_(buf_size, DqnMemStack::PushType::Tail);
DqnMem_Set(buf, 'X', buf_size);
for (auto i = 0; i < buf_size; i++) DQN_ASSERT(buf[i] == 'X');
isize old_buf_size = buf_size;
buf_size = DQN_MEGABYTE(2);
buf = (char *)api->Realloc(buf, old_buf_size, buf_size);
for (auto i = 0; i < old_buf_size; i++)
DQN_ASSERT(buf[i] == 'X');
DqnMem_Set(buf, '@', buf_size);
DQN_ASSERT(block_before != stack.block);
DQN_ASSERT(block_before == stack.block->prev_block);
stack.Pop(buf);
DQN_ASSERT(block_before == stack.block);
DQN_ASSERT(tail_before == stack.block->tail);
DQN_ASSERT(stack.block->head == stack.block->memory);
stack.Free();
}
Log(Status::Ok, "Allocator MemAPI callback, realloc insufficient size so expand");
}
// TODO(doyle): Realloc to smaller size logic
#endif
}
}

View File

@ -1,50 +0,0 @@
struct DqnProcess
{
};
void DqnOS_Test()
{
// pid_t pid = vfork();
// if (pid == 0)
// {
// char const *argv[] = {"jim", "jams", NULL};
// char const *envp[] = {"some", "environment", NULL};
// chdir("/home/usr/loki/");
// execve(cmd, argv, envp);
// perror("Could not execute");
// }
#if defined(DQN__IS_WIN32)
// CreateProcessW();
WSAData wsaData;
int result = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (result != 0)
{
fprintf(stderr, "WSAStartup failed: %d\n", result);
return;
}
addrinfo hints = {};
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
addrinfo *foundAddr = nullptr;
result = getaddrinfo("127.0.0.1", "38151", &hints, &foundAddr);
if (result != 0)
{
fprintf(stderr, "getaddrinfo failed: %d\n", result);
WSACleanup();
return;
}
SOCKET connectSocket = socket(foundAddr->ai_family, foundAddr->ai_socktype, foundAddr->ai_protocol);
if (connectSocket == INVALID_SOCKET)
{
fprintf(stderr, "socket failed: %d\n", WSAGetLastError());
freeaddrinfo(foundAddr);
WSACleanup();
return;
}
#endif
}

View File

@ -1,919 +0,0 @@
#ifndef DQN_REFLECT_H
#define DQN_REFLECT_H
#define DQN_REFLECT
#define DQN_REFLECT_META(...)
//
// HOW TO REFLECT ANNOTATED CODE
// Define in the preprocessor, DQN_REFLECT_IMPLEMENTATION and compile
// Dqn_Reflect.h to produce the metaprogram binary. Run the binary on the
// desired C++ source files which will generate a DqnReflect_Generated.cpp
//
//
// DqnReflect.exe <filename>.[c|cpp|h] ...
//
//
// HOW TO ANNOTATE CODE
// This header file should be included in all files containing information you
// wish to reflect, you may reflect C-like data structures, such as in the
// following example.
//
//
// Your Source Code
//
#if 0
DQN_REFLECT enum struct OpenGLShader
{
Invalid,
Rect DQN_REFLECT_META(VertexShaderFilePath = "Rect.vert", FragmentShaderFilePath = "Rect.frag"),
Text DQN_REFLECT_META(VertexShaderFilePath = "Text.vert", FragmentShaderFilePath = "Text.frag"),
};
#endif
//
// Generated code in DqnReflect_Generated.cpp
//
#if 0
#ifndef DQN_REFLECT_GENERATED_H
#define DQN_REFLECT_GENERATED_H
//
// OpenGL.h
//
#if !defined(DQN_REFLECT_DISABLE_OPENGL_H)
char const *DqnReflect_OpenGLShader_Strings[] = {"Invalid", "Bitmap", "Text" };
char const *DqnReflect_EnumString(OpenGLShader val)
{
if (val == OpenGLShader::Invalid) return DqnReflect_OpenGLShader_Strings[0]; // "Invalid"
if (val == OpenGLShader::Rect) return DqnReflect_OpenGLShader_Strings[1]; // "Rect"
if (val == OpenGLShader::Bitmap) return DqnReflect_OpenGLShader_Strings[2]; // "Bitmap"
return nullptr;
}
char const *DqnReflect_VertexFilePathMetadata(OpenGLShader val)
{
if (val == OpenGLShader::Rect) return "Rect.vert";
if (val == OpenGLShader::Bitmap) return "Bitmap.vert";
return nullptr;
}
char const *DqnReflect_FragmentFilePathMetadata(OpenGLShader val)
{
if (val == OpenGLShader::Rect) return "Rect.frag";
if (val == OpenGLShader::Bitmap) return "Bitmap.frag";
return nullptr;
}
#endif // DQN_REFLECT_DISABLE_OPENGL_H
#endif // DQN_REFLECT_GENERATED_H
#endif
#ifdef DQN_REFLECT_IMPLEMENTATION
#include <assert.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
using usize = size_t;
using isize = ptrdiff_t;
using i64 = int64_t;
using i32 = int32_t;
using b32 = int32_t;
using u8 = uint8_t;
template <typename Proc>
struct Defer
{
Proc proc;
Defer(Proc p) : proc(p) {}
~Defer() { proc(); }
};
struct DeferHelper
{
template <typename Lambda>
Defer<Lambda> operator+(Lambda lambda) { return Defer<Lambda>(lambda); }
};
#define STR_LITERAL(str) {str, CHAR_COUNT(str)}
struct StringLiteral
{
StringLiteral() = default;
StringLiteral(char *string, int string_len) : str(string) , len(string_len) { }
char *str;
int len;
};
template <typename T>
struct LinkedList
{
T data;
LinkedList *next;
};
#define REFLECT_MAX(a, b) ((a) > (b)) ? (a) : (b)
#define ARRAY_COUNT(str) sizeof(str)/sizeof(str[0])
#define CHAR_COUNT(str) (ARRAY_COUNT(str) - 1)
#define TOKEN_COMBINE(x, y) x ## y
#define TOKEN_COMBINE2(x, y) TOKEN_COMBINE(x, y)
#define DEFER auto const TOKEN_COMBINE(defer_lambda_, __COUNTER__) = DeferHelper() + [&]()
#define KILOBYTE(val) (1024ULL * (val))
#define MEGABYTE(val) (1024ULL * KILOBYTE(val))
//
// Memory Utilities
//
struct MemArena
{
void *memory;
usize size;
usize used;
};
struct MemArenaScopedRegion
{
MemArenaScopedRegion (MemArena *arena_, usize used_) : arena(arena_), used(used_) {}
~MemArenaScopedRegion() { arena->used = used; }
MemArena *arena;
usize used;
};
static MemArena global_main_arena;
#define MEM_ARENA_ALLOC_ARRAY(arena, Type, num) static_cast<Type *>(MemArena_Alloc(arena, sizeof(Type) * num))
#define MEM_ARENA_ALLOC_STRUCT(arena, Type) static_cast<Type *>(MemArena_Alloc(arena, sizeof(Type)))
MemArena MemArena_Init(void *memory, usize size)
{
MemArena result = {};
result.memory = memory;
result.size = size;
result.used = 0;
return result;
}
MemArenaScopedRegion MemArena_MakeScopedRegion(MemArena *arena)
{
return MemArenaScopedRegion(arena, arena->used);
}
void *MemArena_Alloc(MemArena *arena, usize size)
{
assert(arena->used + size <= arena->size);
void *result = static_cast<uint8_t *>(arena->memory) + arena->used;
arena->used += size;
return result;
}
template <typename T> void EraseStableFromCArray(T *array, isize len, isize max, isize index);
#define FIXED_ARRAY_TEMPLATE_DECL template <typename T, int MAX_>
FIXED_ARRAY_TEMPLATE_DECL struct FixedArray
{
FixedArray() = default;
T data[MAX_];
isize len;
isize Max() const { return MAX_; }
T const &operator[] (isize i) const { assert(i >= 0 && i < len); return data[i]; }
T &operator[] (isize i) { assert(i >= 0 && i < len); return data[i]; }
T const *begin () const { return data; }
T const *end () const { return data + len; }
T *begin () { return data; }
T *end () { return data + len; }
};
FIXED_ARRAY_TEMPLATE_DECL FixedArray<T, MAX_> FixedArray_Init (T const *item, int num) { FixedArray<T, MAX_> result = {}; FixedArray_Add(&result, item, num); return result; }
FIXED_ARRAY_TEMPLATE_DECL T *FixedArray_Add (FixedArray<T, MAX_> *a, T const *items, int num) { assert(a->len + num <= MAX_); T *result = static_cast<T *>(MemCopy(a->data + a->len, items, sizeof(T) * num)); a->len += num; return result; }
FIXED_ARRAY_TEMPLATE_DECL T *FixedArray_Add (FixedArray<T, MAX_> *a, T const item) { assert(a->len < MAX_); a->data[a->len++] = item; return &a->data[a->len - 1]; }
FIXED_ARRAY_TEMPLATE_DECL T *FixedArray_Make (FixedArray<T, MAX_> *a, int num) { assert(a->len + num <= MAX_); T *result = a->data + a->len; a->len += num; return result;}
FIXED_ARRAY_TEMPLATE_DECL void FixedArray_Clear (FixedArray<T, MAX_> *a) { a->len = 0; }
FIXED_ARRAY_TEMPLATE_DECL void FixedArray_EraseStable (FixedArray<T, MAX_> *a, isize index) { EraseStableFromCArray<T>(a->data, a->len--, a.Max(), index); }
FIXED_ARRAY_TEMPLATE_DECL void FixedArray_EraseUnstable(FixedArray<T, MAX_> *a, isize index) { assert(index >= 0 && index < a->len); if (--a->len == 0) return; a->data[index] = a->data[a->len]; }
//
// String Utilities
//
b32 CharIsAlpha (char ch) { return (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'); }
b32 CharIsDigit (char ch) { return (ch >= '0' && ch <= '9'); }
b32 CharIsAlphaNum (char ch) { return CharIsAlpha(ch) || CharIsDigit(ch); }
b32 CharIsWhitespace(char ch) { return (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r'); }
char const *StrSkipToChar(char const *src, char ch)
{
char const *result = src;
while (result && result[0] && result[0] != ch) ++result;
return result;
}
char const *StrSkipToNextAlphaNum(char const *src)
{
char const *result = src;
while (result && result[0] && !CharIsAlphaNum(result[0])) ++result;
return result;
}
char const *StrSkipToNextDigit(char const *src)
{
char const *result = src;
while (result && result[0] && !CharIsDigit(result[0])) ++result;
return result;
}
char const *StrSkipToNextChar(char const *src)
{
char const *result = src;
while (result && result[0] && !CharIsAlpha(result[0])) ++result;
return result;
}
char const *StrSkipToNextWord(char const *src)
{
char const *result = src;
while (result && result[0] && !CharIsWhitespace(result[0])) ++result;
while (result && result[0] && CharIsWhitespace(result[0])) ++result;
return result;
}
char const *StrSkipToNextWhitespace(char const *src)
{
char const *result = src;
while (result && result[0] && !CharIsWhitespace(result[0])) ++result;
return result;
}
char const *StrSkipWhitespace(char const *src)
{
char const *result = src;
while (result && result[0] && CharIsWhitespace(result[0])) ++result;
return result;
}
char const *StrSkipToNextWordInplace(char const **src) { *src = StrSkipToNextWord(*src); return *src; }
char const *StrSkipWhitespaceInplace(char const **src) { *src = StrSkipWhitespace(*src); return *src; }
char *StrFind(StringLiteral src, StringLiteral find)
{
char *buf_ptr = src.str;
char *buf_end = buf_ptr + src.len;
char *result = nullptr;
for (;*buf_ptr; ++buf_ptr)
{
int len_remaining = static_cast<int>(buf_end - buf_ptr);
if (len_remaining < find.len) break;
if (strncmp(buf_ptr, find.str, find.len) == 0)
{
result = buf_ptr;
break;
}
}
return result;
}
b32 StrCmp(StringLiteral a, StringLiteral b)
{
if (a.len != b.len)
return false;
b32 result = (memcmp(a.str, b.str, a.len) == 0);
return result;
}
//
// CPP Tokenisers/Tokens
//
#define CPP_TOKEN_TYPE_X_MACRO \
X(EndOfStream, "End Of Stream") \
X(LeftBrace, "{") \
X(RightBrace, "}") \
X(OpenParen, "(") \
X(CloseParen, ")") \
X(Comma, ",") \
X(Colon, ":") \
X(FwdSlash, "/") \
X(Comment, "comment") \
X(LessThan, "<") \
X(GreaterThan, ">") \
X(Equals, "=") \
X(String, "\"") \
X(SemiColon, ";") \
X(Identifier, "Identifier") \
X(Number, "[0-9]") \
X(Hash, "#")
#define X(decl, str) decl,
enum struct CPPTokenType
{
CPP_TOKEN_TYPE_X_MACRO
};
#undef X
#define X(decl, str) str,
char const *CPPTokenType_Strings[]
{
CPP_TOKEN_TYPE_X_MACRO
};
#undef X
struct CPPToken
{
CPPTokenType type;
char *str;
int len;
};
struct CPPReflectMetadataEntry
{
StringLiteral key;
StringLiteral value;
};
using CPPReflectMetadataArray = FixedArray<CPPReflectMetadataEntry, 8>;
struct CPPEnumValuesLinkedList
{
StringLiteral value;
CPPReflectMetadataArray metadata_array;
CPPEnumValuesLinkedList *next;
};
struct CPPTokeniser
{
CPPToken *tokens;
int tokens_index;
int tokens_len;
int tokens_max;
int spaces_per_indent;
int indent_level;
FILE *output_file;
};
void CPPTokeniser_SprintfToFile(CPPTokeniser *tokeniser, char const *fmt, ...)
{
int const num_spaces = tokeniser->spaces_per_indent * tokeniser->indent_level;
fprintf(tokeniser->output_file, "%*s", num_spaces, "");
va_list va;
va_start(va, fmt);
vfprintf(tokeniser->output_file, fmt, va);
va_end(va);
}
void CPPTokeniser_SprintfToFileNoIndenting(CPPTokeniser *tokeniser, char const *fmt, ...)
{
va_list va;
va_start(va, fmt);
vfprintf(tokeniser->output_file, fmt, va);
va_end(va);
}
CPPToken CPPTokeniser_NextToken(CPPTokeniser *tokeniser)
{
CPPToken result = tokeniser->tokens[tokeniser->tokens_index++];
if (result.type == CPPTokenType::LeftBrace) tokeniser->indent_level++;
else if (result.type == CPPTokenType::RightBrace) tokeniser->indent_level--;
assert(tokeniser->indent_level >= 0);
return result;
}
CPPToken CPPTokeniser_PeekToken(CPPTokeniser *tokeniser)
{
CPPToken result = tokeniser->tokens[tokeniser->tokens_index];
return result;
}
void CPPTokeniser_RewindToken(CPPTokeniser *tokeniser)
{
tokeniser->tokens[--tokeniser->tokens_index];
}
CPPToken CPPTokeniser_PrevToken(CPPTokeniser *tokeniser)
{
CPPToken result = {};
result.type = CPPTokenType::EndOfStream;
if (tokeniser->tokens_index > 0)
result = tokeniser->tokens[tokeniser->tokens_index - 1];
return result;
}
CPPToken *CPPTokeniser_MakeToken(CPPTokeniser *tokeniser)
{
assert(tokeniser->tokens_len < tokeniser->tokens_max);
CPPToken *result = tokeniser->tokens + tokeniser->tokens_len++;
return result;
}
//
// CPP Parsing Helpers
//
b32 IsIdentifierToken(CPPToken token, StringLiteral expect_str)
{
b32 result = (token.type == CPPTokenType::Identifier) && (StrCmp(StringLiteral(token.str, token.len), expect_str));
return result;
}
b32 ExpectToken(CPPToken token, CPPTokenType type)
{
b32 result = token.type == type;
if (!result)
{
fprintf(stdout, "Expected token type: %s received: %.*s\n", CPPTokenType_Strings[(int)type], token.len, token.str);
fprintf(stdout, "Context: %.*s\n\n", (token.len > 100) ? 100 : token.len, token.str);
}
return result;
}
//
// CPP Parsing Functions
//
CPPReflectMetadataArray ParseCPPReflectMeta(CPPTokeniser *tokeniser)
{
CPPReflectMetadataArray result = {};
CPPToken token = CPPTokeniser_NextToken(tokeniser);
if (!ExpectToken(token, CPPTokenType::OpenParen))
return result;
for (token = CPPTokeniser_NextToken(tokeniser);
token.type != CPPTokenType::EndOfStream && token.type != CPPTokenType::CloseParen;
token = CPPTokeniser_NextToken(tokeniser))
{
if (token.type == CPPTokenType::Identifier)
{
auto metadata_key = StringLiteral(token.str, token.len);
CPPToken peek_token = CPPTokeniser_PeekToken(tokeniser);
if (!ExpectToken(peek_token, CPPTokenType::Equals))
continue;
token = CPPTokeniser_NextToken(tokeniser);
peek_token = CPPTokeniser_PeekToken(tokeniser);
if (peek_token.type == CPPTokenType::String || peek_token.type == CPPTokenType::Identifier)
{
token = CPPTokeniser_NextToken(tokeniser);
if (IsIdentifierToken(token, STR_LITERAL("nullptr"))) continue;
CPPReflectMetadataEntry *entry = FixedArray_Make(&result, 1);
entry->key = metadata_key;
entry->value = StringLiteral(token.str, token.len);
}
}
}
while (token.type != CPPTokenType::EndOfStream && token.type != CPPTokenType::Comma)
token = CPPTokeniser_NextToken(tokeniser);
if (token.type == CPPTokenType::EndOfStream)
CPPTokeniser_RewindToken(tokeniser);
return result;
}
void ParseCPPEnum(CPPTokeniser *tokeniser)
{
CPPToken token = CPPTokeniser_NextToken(tokeniser);
b32 enum_is_struct_or_class = false;
if (IsIdentifierToken(token, STR_LITERAL("class")) ||
IsIdentifierToken(token, STR_LITERAL("struct")))
{
enum_is_struct_or_class = true;
token = CPPTokeniser_NextToken(tokeniser);
}
if (!ExpectToken(token, CPPTokenType::Identifier))
return;
CPPToken const enum_name = token;
token = CPPTokeniser_NextToken(tokeniser);
if (!ExpectToken(token, CPPTokenType::LeftBrace))
return;
b32 has_metadata = false;
CPPEnumValuesLinkedList *start_enum_value_token = nullptr, *enum_value_token = nullptr;
MemArenaScopedRegion mem_region = MemArena_MakeScopedRegion(&global_main_arena);
for (token = CPPTokeniser_NextToken(tokeniser);
token.type != CPPTokenType::EndOfStream && token.type != CPPTokenType::SemiColon;
token = CPPTokeniser_NextToken(tokeniser))
{
if (token.type == CPPTokenType::Identifier)
{
CPPToken enum_value = token;
token = CPPTokeniser_NextToken(tokeniser);
CPPReflectMetadataArray metadata_array = {};
if (IsIdentifierToken(token, STR_LITERAL("DQN_REFLECT_META")))
{
has_metadata = true;
metadata_array = ParseCPPReflectMeta(tokeniser);
}
if (!start_enum_value_token)
{
start_enum_value_token = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, CPPEnumValuesLinkedList);
enum_value_token = start_enum_value_token;
}
else
{
enum_value_token->next = MEM_ARENA_ALLOC_STRUCT(&global_main_arena, CPPEnumValuesLinkedList);
enum_value_token = enum_value_token->next;
}
(*enum_value_token) = {};
enum_value_token->metadata_array = metadata_array;
enum_value_token->value = StringLiteral(enum_value.str, enum_value.len);
}
}
//
// Write Stringified Enum Array
//
{
CPPTokeniser_SprintfToFile(tokeniser, "char const *DqnReflect_%.*s_Strings[] = {", enum_name.len, enum_name.str);
tokeniser->indent_level++;
for (CPPEnumValuesLinkedList *link = start_enum_value_token; link; link = link->next)
{
StringLiteral enum_value = link->value;
CPPTokeniser_SprintfToFileNoIndenting(tokeniser, "\"%.*s\", ", enum_value.len, enum_value.str);
}
tokeniser->indent_level--;
CPPTokeniser_SprintfToFile(tokeniser, "};\n\n");
}
//
// Write ReflectEnumString Function
//
{
CPPTokeniser_SprintfToFile(tokeniser, "char const *DqnReflect_EnumString(%.*s val)\n{\n", enum_name.len, enum_name.str);
tokeniser->indent_level++;
DEFER
{
CPPTokeniser_SprintfToFile(tokeniser, "return nullptr;\n");
tokeniser->indent_level--;
CPPTokeniser_SprintfToFile(tokeniser, "}\n\n");
};
struct SourceCode
{
StringLiteral decl;
StringLiteral enum_value;
};
LinkedList<SourceCode> src_code = {};
int longest_decl_len = 0;
{
LinkedList<SourceCode> *curr_src_code = nullptr;
char const *fmt = (enum_is_struct_or_class) ? "if (val == %.*s::%.*s) " : "if (val == %.*s) ";
for (CPPEnumValuesLinkedList *link = start_enum_value_token; link; link = link->next)
{
if (!curr_src_code) curr_src_code = &src_code;
else
{
curr_src_code->next = static_cast<LinkedList<SourceCode> *>( MemArena_Alloc(&global_main_arena, sizeof(*curr_src_code)));
curr_src_code = curr_src_code->next;
}
StringLiteral enum_value = link->value;
int required_len = 0;
if (enum_is_struct_or_class) required_len = snprintf(nullptr, 0, fmt, enum_name.len, enum_name.str, enum_value.len, enum_value.str) + 1;
else required_len = snprintf(nullptr, 0, fmt, enum_value.len, enum_value.str) + 1;
longest_decl_len = REFLECT_MAX(longest_decl_len, required_len);
curr_src_code->data.decl.str = MEM_ARENA_ALLOC_ARRAY(&global_main_arena, char, required_len);
curr_src_code->data.decl.len = required_len;
curr_src_code->data.enum_value = enum_value;
if (enum_is_struct_or_class) snprintf(curr_src_code->data.decl.str, curr_src_code->data.decl.len, fmt, enum_name.len, enum_name.str, enum_value.len, enum_value.str);
else snprintf(curr_src_code->data.decl.str, curr_src_code->data.decl.len, fmt, enum_value.len, enum_value.str);
}
curr_src_code->next = nullptr;
}
int enum_index = 0;
for (LinkedList<SourceCode> *src_code_ptr = &src_code;
src_code_ptr;
src_code_ptr = src_code_ptr->next, ++enum_index)
{
StringLiteral enum_value = src_code_ptr->data.enum_value;
int padding = longest_decl_len - src_code_ptr->data.decl.len;
CPPTokeniser_SprintfToFile(tokeniser, "%.*s%*s", src_code_ptr->data.decl.len, src_code_ptr->data.decl.str, padding, "");
CPPTokeniser_SprintfToFileNoIndenting(tokeniser,
"return DqnReflect_%.*s_Strings[%d]; // \"%.*s\"\n",
enum_name.len, enum_name.str,
enum_index,
enum_value.len, enum_value.str);
}
}
//
// Write User Annotated Metadata Getter Functions
//
if (has_metadata)
{
struct CPPDeclToValue
{
StringLiteral cpp_decl;
StringLiteral value;
};
struct MetadataEntry
{
StringLiteral key;
FixedArray<CPPDeclToValue, 32> cpp_decl_to_val;
};
FixedArray<MetadataEntry, 32> metadata_entries = {};
for (CPPEnumValuesLinkedList *link = start_enum_value_token;
link;
link = link->next)
{
for (CPPReflectMetadataEntry const &reflect_entry : link->metadata_array)
{
MetadataEntry *metadata_entry_to_append_to = nullptr;
for (MetadataEntry &check_metadata_entry : metadata_entries)
{
if (StrCmp(check_metadata_entry.key, reflect_entry.key))
{
metadata_entry_to_append_to = &check_metadata_entry;
break;
}
}
if (!metadata_entry_to_append_to)
{
metadata_entry_to_append_to = FixedArray_Make(&metadata_entries, 1);
metadata_entry_to_append_to->key = reflect_entry.key;
}
CPPDeclToValue decl_to_val = {};
decl_to_val.cpp_decl = StringLiteral(link->value.str, link->value.len);
decl_to_val.value = reflect_entry.value;
FixedArray_Add(&metadata_entry_to_append_to->cpp_decl_to_val, decl_to_val);
}
}
for (MetadataEntry const &metadata : metadata_entries)
{
CPPTokeniser_SprintfToFile(tokeniser,
"char const *DqnReflect_%.*sMetadata(%.*s val)\n{\n",
metadata.key.len, metadata.key.str,
enum_name.len, enum_name.str);
tokeniser->indent_level++;
DEFER
{
CPPTokeniser_SprintfToFile(tokeniser, "return nullptr;\n");
tokeniser->indent_level--;
CPPTokeniser_SprintfToFile(tokeniser, "}\n\n");
};
int enum_index = 0;
for (CPPDeclToValue const &decl_to_val : metadata.cpp_decl_to_val)
{
StringLiteral const *cpp_decl = &decl_to_val.cpp_decl;
StringLiteral const *value = &decl_to_val.value;
if (enum_is_struct_or_class)
{
CPPTokeniser_SprintfToFile(tokeniser,
"if (val == %.*s::%.*s) ",
enum_name.len, enum_name.str,
cpp_decl->len, cpp_decl->str);
}
else
{
CPPTokeniser_SprintfToFile(tokeniser,
"if (val == %.*s) ",
cpp_decl->len, cpp_decl->str);
}
CPPTokeniser_SprintfToFileNoIndenting(tokeniser, "return \"%.*s\";\n", value->len, value->str);
}
}
}
}
int main(int argc, char *argv[])
{
if (argc < 1)
{
fprintf(stdout, "Usage: %s [<filename>, ...]", argv[0]);
return 0;
}
usize main_arena_mem_size = MEGABYTE(2);
void *main_arena_mem = malloc(main_arena_mem_size);
global_main_arena = MemArena_Init(main_arena_mem, main_arena_mem_size);
FILE *output_file = fopen("DqnReflect_Generated.cpp", "w");
fprintf(output_file,
"#ifndef DQN_REFLECT_GENERATED_H\n"
"#define DQN_REFLECT_GENERATED_H\n\n"
"// This is an auto generated file using Dqn_Reflect\n"
"\n");
for (usize arg_index = 1; arg_index < argc; ++arg_index)
{
MemArenaScopedRegion mem_region = MemArena_MakeScopedRegion(&global_main_arena);
char *file_name = argv[arg_index];
FILE *file = fopen(file_name, "rb");
fseek(file, 0, SEEK_END);
usize file_size = ftell(file);
rewind(file);
char *file_buf = (char *)MemArena_Alloc(&global_main_arena, file_size + 1);
file_buf[file_size] = 0;
if (fread(file_buf, file_size, 1, file) != 1)
{
fprintf(stderr, "Failed to fread: %zu bytes into buffer from file: %s\n", file_size, file_name);
continue;
}
int const file_name_len = (int)strlen(file_name);
int file_include_contents_hash_define_len = 0;
char *file_include_contents_hash_define = nullptr;
{
char *extracted_file_name_buf = static_cast<char *>(MemArena_Alloc(&global_main_arena, file_name_len));
int extracted_file_name_len = 0;
for (int i = file_name_len - 1; i >= 0; i--, extracted_file_name_len++)
{
char ch = file_name[i];
if (ch == '.')
ch = '_';
if (ch >= 'a' && ch <= 'z') ch -= 'a' - 'A';
if (ch == '\\' || ch == '/')
break;
extracted_file_name_buf[i] = ch;
}
file_include_contents_hash_define = extracted_file_name_buf + file_name_len - extracted_file_name_len;
file_include_contents_hash_define_len = extracted_file_name_len;
}
fprintf(output_file,
"//\n"
"// %s\n"
"//\n"
"\n"
"#if !defined(DQN_REFLECT_DISABLE_%.*s)\n",
file_name,
file_include_contents_hash_define_len,
file_include_contents_hash_define);
CPPTokeniser tokeniser = {};
tokeniser.spaces_per_indent = 4;
tokeniser.output_file = output_file;
tokeniser.tokens_max = 16384;
tokeniser.tokens = MEM_ARENA_ALLOC_ARRAY(&global_main_arena, CPPToken, tokeniser.tokens_max);
StringLiteral const REFLECT_MARKER = STR_LITERAL("DQN_REFLECT");
char *file_buf_end = file_buf + file_size;
StringLiteral buffer = StringLiteral(file_buf, file_size);
for (char *ptr = StrFind(buffer, REFLECT_MARKER);
ptr;
ptr = StrFind(buffer, REFLECT_MARKER))
{
ptr += REFLECT_MARKER.len;
for (; ptr;)
{
while (CharIsWhitespace(ptr[0])) ptr++;
if (!ptr[0]) break;
CPPToken *token = CPPTokeniser_MakeToken(&tokeniser);
token->str = ptr++;
token->len = 1;
switch(token->str[0])
{
case '{': { token->type = CPPTokenType::LeftBrace; } break;
case '}': { token->type = CPPTokenType::RightBrace; } break;
case '(': { token->type = CPPTokenType::OpenParen; } break;
case ')': { token->type = CPPTokenType::CloseParen; } break;
case ',': { token->type = CPPTokenType::Comma; } break;
case ';': { token->type = CPPTokenType::SemiColon; } break;
case '=': { token->type = CPPTokenType::Equals; } break;
case '<': { token->type = CPPTokenType::LessThan; } break;
case '>': { token->type = CPPTokenType::GreaterThan; } break;
case ':': { token->type = CPPTokenType::Colon; } break;
case '/':
{
token->type = CPPTokenType::FwdSlash;
if (ptr[0] == '/')
{
while (ptr[0] == ' ' || ptr[0] == '\t') ptr++;
token->str = ptr;
while (ptr[0] != '\n') ptr++;
token->type = CPPTokenType::Comment;
token->len = ptr - token->str;
}
}
break;
default:
{
ptr--;
if (ptr[0] == '"')
{
token->type = CPPTokenType::String;
for (token->str = ++ptr;;)
{
while (ptr[0] != '"') ptr++;
token->len = ptr - token->str;
if (ptr[-1] != '\\')
{
ptr++;
break;
}
}
}
else
{
if (CharIsDigit(ptr[0]))
{
while (CharIsDigit(ptr[0]) || ptr[0] == 'x' || ptr[0] == 'b' || ptr[0] == 'e' || ptr[0] == '.' || ptr[0] == 'f')
ptr++;
token->type = CPPTokenType::Number;
}
else
{
token->type = CPPTokenType::Identifier;
if (CharIsAlpha(ptr[0]) || ptr[0] == '_')
{
ptr++;
while (CharIsAlphaNum(ptr[0]) || ptr[0] == '_') ptr++;
}
}
token->len = ptr - token->str;
}
}
break;
}
if (token->len == 0)
{
*token = {};
tokeniser.tokens_len--;
}
else if (token->type == CPPTokenType::SemiColon)
{
break;
}
}
buffer.str = ptr;
buffer.len = static_cast<int>(file_buf_end - ptr);
}
CPPToken *sentinel = CPPTokeniser_MakeToken(&tokeniser);
sentinel->type = CPPTokenType::EndOfStream;
for (CPPToken token = CPPTokeniser_NextToken(&tokeniser);
token.type != CPPTokenType::EndOfStream;
token = CPPTokeniser_NextToken(&tokeniser))
{
#if 0
Token const *token = tokens + index;
fprintf(stdout, "%.*s", token->len, token->str);
if (index < (tokens_index - 1)) fprintf(stdout, " -> ");
#endif
if (token.type == CPPTokenType::Identifier)
{
if (StrCmp(StringLiteral(token.str, token.len), STR_LITERAL("enum")))
ParseCPPEnum(&tokeniser);
}
}
fprintf(output_file, "#endif // DQN_REFLECT_DISABLE_%.*s\n\n",
file_include_contents_hash_define_len,
file_include_contents_hash_define);
}
fprintf(output_file, "#endif // DQN_REFLECT_GENERATED_H\n");
fclose(output_file);
return 0;
}
#endif // DQN_REFLECT_IMPLEMENTATION
#endif // DQN_REFLECT_H

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27428.2037
MinimumVisualStudioVersion = 10.0.40219.1
Project("{911E67C6-3D85-4FCE-B560-20A9C3E3FF48}") = "DqnUnitTest", "bin\DqnUnitTest.exe", "{F1606403-E704-4C35-8354-8E33DE4F5CCF}"
ProjectSection(DebuggerProjectSystem) = preProject
PortSupplier = 00000000-0000-0000-0000-000000000000
Executable = F:\dev\dqn\bin\DqnUnitTest.exe
RemoteMachine = THAI-XPS13
StartingDirectory = F:\dev\dqn\
Environment = Default
LaunchingEngine = 00000000-0000-0000-0000-000000000000
UseLegacyDebugEngines = No
LaunchSQLEngine = No
AttachLaunchAction = No
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F1606403-E704-4C35-8354-8E33DE4F5CCF}.Release|x64.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8DD71C86-534C-4A9C-A217-CBA13DE8DA5A}
EndGlobalSection
EndGlobal

View File

@ -1,88 +0,0 @@
void DqnVHashTable_Test()
{
LOG_HEADER();
struct Block
{
int x;
};
using Height = u32;
{
Block block = {};
DqnVHashTable<Height, Block> table = {};
DQN_DEFER { table.Free(); };
table.Set(12, block);
Block *getResult = table.Get(12);
Block *operatorResult = table[12];
DQN_ASSERT(operatorResult == getResult);
DQN_ASSERT(operatorResult != nullptr);
Log(Status::Ok, "Set and get element using key");
table.Erase(12);
getResult = table.Get(12);
operatorResult = table[12];
DQN_ASSERT(operatorResult == getResult);
DQN_ASSERT(operatorResult == nullptr);
Log(Status::Ok, "Erase element using key");
}
{
Block blocks[] = {{0}, {1}, {2}, {3}, {4}};
DqnVHashTable<Height, Block> table = {};
DQN_DEFER { table.Free(); };
table.Set(1, blocks[0]);
table.Set(2, blocks[1]);
table.Set(3, blocks[2]);
table.Set(4, blocks[3]);
table.Set(5, blocks[4]);
{
bool blockSeen[DQN_ARRAY_COUNT(blocks)] = {};
isize blocksSeen = 0;
for (auto const &entry : table)
{
Block const *block = &entry.item;
DQN_ASSERT(blockSeen[block->x] == false);
blockSeen[block->x] = true;
blocksSeen++;
}
DQN_ASSERT(blocksSeen == DQN_ARRAY_COUNT(blockSeen));
Log(Status::Ok, "Auto iterator using prefix operator++");
}
{
bool blockSeen[DQN_ARRAY_COUNT(blocks)] = {};
isize blocksSeen = 0;
for (auto it = table.begin(); it != table.end();)
{
Block *block = &it.entry->item;
DQN_ASSERT(blockSeen[block->x] == false);
blockSeen[block->x] = true;
blocksSeen++;
it = it + 1;
}
DQN_ASSERT(blocksSeen == DQN_ARRAY_COUNT(blockSeen));
Log(Status::Ok, "Auto iterator using operator+");
}
{
bool blockSeen[DQN_ARRAY_COUNT(blocks)] = {};
isize blocksSeen = 0;
for (auto it = table.begin(); it != table.end(); it++)
{
Block *block = &it.entry->item;
DQN_ASSERT(blockSeen[block->x] == false);
blockSeen[block->x] = true;
blocksSeen++;
}
DQN_ASSERT(blocksSeen == DQN_ARRAY_COUNT(blockSeen));
Log(Status::Ok, "Auto iterator using postfix operator++");
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,71 +0,0 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or
@REM vcvarsall.bat to setup command-line compiler.
@echo OFF
set ProjectName=DqnUnitTest
set CompileEntryPoint=..\DqnUnitTest.cpp
REM Build tags file if you have ctags in path
where /q ctags
if %errorlevel%==0 (
REM When parsing a C++ member function definition (e.g. "className::function"),
REM ctags cannot determine whether the scope specifier is a class name or
REM a namespace specifier and always lists it as a class name in the scope
REM portion of the extension fields. Also, if a C++ function is defined outside
REM of the class declaration (the usual case), the access specification (i.e.
REM public, protected, or private) and implementation information (e.g. virtual,
REM pure virtual) contained in the function declaration are not known when the
REM tag is generated for the function definition. -c++-kinds=+p fixes that
REM The --fields=+iaS option:
REM a Access (or export) of class members
REM i Inheritance information
REM S Signature of routine (e.g. prototype or parameter list)
REM
REM The --extra=+q option:
REM By default, ctags only generates tags for separate identifiers found in
REM the source files. With --extras=+q option, then ctags will also generate
REM a second, class-qualified tag for each class member
ctags -R --c++-kinds=+p --fields=+iaS --extras=+q
)
REM Check if build tool is on path
REM >nul, 2>nul will remove the output text from the where command
where cl.exe >nul 2>nul
if %errorlevel%==1 call msvc86.bat
REM Drop compilation files into build folder
IF NOT EXIST bin mkdir bin
pushd bin
REM EHa- disable exception handling (but we use for algorithms so /EHsc)
REM GR- disable c runtime type information (we don't use)
REM MD use dynamic runtime library
REM MT use static runtime library, so build and link it into exe
REM Oi enable intrinsics optimisation, let us use CPU intrinsics if there is one
REM instead of generating a call to external library (i.e. CRT).
REM Zi enables debug data, Z7 combines the debug files into one.
REM W4 warning level 4
REM WX treat warnings as errors
REM wd4201 ignore: nonstandard extension used: nameless struct/union
set CompileFlags=-EHsc -GR- -Oi -MT -Z7 -W4 -WX -wd4201 -FC -Od -wd4127 /P
REM Include directories
set IncludeFlags=
REM Link libraries
set LinkLibraries=user32.lib ws2_32.lib
REM incrmenetal:no, turn incremental builds off
REM opt:ref, try to remove functions from libs that are referenced at all
set LinkFlags=-incremental:no -opt:ref -machine:x64
cl %CompileFlags% %CompileEntryPoint% %IncludeFlags% /link %LinkLibraries% %LinkFlags% /nologo /OUT:"%ProjectName%.exe"
REM cl /P /c %CompileFlags% %CompileEntryPoint%
popd

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +0,0 @@
all: DqnUnitTest.cpp
mkdir -p bin
g++ -std=c++14 -o bin/DqnUnitTest DqnUnitTest.cpp -lm -Wall -pthread -ggdb