Do massive overhaul and simplification of DN

This commit is contained in:
2026-03-07 20:40:16 +11:00
parent ad019541a4
commit 19df3b75ce
53 changed files with 3880 additions and 5101 deletions
+81 -79
View File
@@ -45,6 +45,83 @@ DN_INIStr8 DN_INI_Str8FromPtr(char const *data, size_t count)
return result;
}
static void DN_INI_Str8BuilderAppend_(DN_INIStr8Builder *builder, char const *fmt, ...)
{
va_list args;
va_list args_copy;
va_start(args, fmt);
va_copy(args_copy, args);
int size_req = vsnprintf(0, 0, fmt, args);
va_end(args);
builder->size_req += size_req;
if (builder->used + size_req <= builder->max) {
vsnprintf(builder->data + builder->used, builder->max - builder->used, fmt, args_copy);
builder->used += size_req;
}
va_end(args_copy);
}
DN_INIStr8FromResult DN_INI_Str8FromINI(DN_INICore const *ini, char *buffer, size_t size)
{
DN_INIStr8FromResult result = {};
DN_INISection const *section_stack[64] = {};
size_t section_stack_count = 0;
if (ini->first_section.child_first)
section_stack[section_stack_count++] = &ini->first_section;
DN_INIStr8Builder builder = {};
builder.data = buffer;
builder.max = size;
DN_INISection *parent_stack[32] = {};
size_t parent_stack_count = 0;
for (; section_stack_count;) {
DN_INISection const *it = section_stack[--section_stack_count];
if (it != &ini->first_section) {
DN_INI_Str8BuilderAppend_(&builder, "[");
for (DN_INISection *parent = it->parent; parent; parent = parent->parent)
if (parent->name.size)
parent_stack[parent_stack_count++] = parent;
for (size_t index = parent_stack_count - 1; index < parent_stack_count; index--) {
DN_INISection *parent = parent_stack[index];
DN_INI_Str8BuilderAppend_(&builder, "%.*s.", (int)parent->name.size, parent->name.data);
}
parent_stack_count = 0;
DN_INI_Str8BuilderAppend_(&builder, "%.*s]\n", (int)it->name.size, it->name.data);
}
for (DN_INIField *field = it->first_field; field; field = field->next) {
DN_INI_Str8BuilderAppend_(&builder, "%.*s = ", (int)field->key.size, field->key.data);
switch (field->value_type) {
case DN_INIFieldType_String: DN_INI_Str8BuilderAppend_(&builder, "%.*s\n", (int)field->value.size, field->value.data); break;
case DN_INIFieldType_Bool: DN_INI_Str8BuilderAppend_(&builder, "%d\n", field->value_bool); break;
case DN_INIFieldType_USize: DN_INI_Str8BuilderAppend_(&builder, "%zu\n", field->value_usize); break;
}
}
if (it->next)
section_stack[section_stack_count++] = it->next;
if (it->child_first)
section_stack[section_stack_count++] = it->child_first;
if (section_stack_count && it != &ini->first_section)
DN_INI_Str8BuilderAppend_(&builder, "\n");
}
result.size_req = builder.size_req;
if (buffer) {
result.str8.data = builder.data;
result.str8.size = builder.used;
result.success = true;
} else {
result.success = true;
}
return result;
}
static bool DN_INI_Str8Eq(DN_INIStr8 lhs, DN_INIStr8 rhs)
{
bool result = lhs.size == rhs.size && DN_INI_Memcmp(lhs.data, rhs.data, lhs.size) == 0;
@@ -442,8 +519,8 @@ DN_INICore DN_INI_ParseFromPtr(char const *buf, size_t count, char *base, size_t
arena.max = base_count;
DN_INICore result = {};
DN_INISection *curr_section = &result.first_section;
DN_INIField *field = 0;
DN_INISection *curr_section = &result.first_section;
DN_INIField *field = 0;
for (;;) {
DN_INIToken token = DN_INI_NextToken(&tokeniser);
if (token.type == DN_INITokenType_EndOfStream)
@@ -651,6 +728,8 @@ DN_INISection *DN_INI_AppendSectionF(DN_INICore *ini, DN_INIArena *arena, DN_INI
result->name.data = (char *)DN_INI_ArenaAlloc(arena, size_req + 1);
result->name.size = size_req;
vsnprintf(result->name.data, result->name.size + 1, fmt, args_copy);
if (!section)
section = &ini->first_section;
if (result) {
if (section) {
@@ -770,83 +849,6 @@ DN_INIField *DN_INI_AppendKeyF(DN_INICore *ini, DN_INIArena *arena, DN_INISectio
return result;
}
static void DN_INI_Str8BuilderAppend(DN_INIStr8Builder *builder, char const *fmt, ...)
{
va_list args;
va_list args_copy;
va_start(args, fmt);
va_copy(args_copy, args);
int size_req = vsnprintf(0, 0, fmt, args);
va_end(args);
builder->size_req += size_req;
if (builder->used + size_req <= builder->max) {
vsnprintf(builder->data + builder->used, builder->max - builder->used, fmt, args_copy);
builder->used += size_req;
}
va_end(args_copy);
}
DN_INIStr8FromResult DN_INI_Str8FromINI(DN_INICore const *ini, char *buffer, size_t size)
{
DN_INIStr8FromResult result = {};
DN_INISection const *section_stack[64] = {};
size_t section_stack_count = 0;
if (ini->first_section.child_first)
section_stack[section_stack_count++] = &ini->first_section;
DN_INIStr8Builder builder = {};
builder.data = buffer;
builder.max = size;
DN_INISection *parent_stack[32] = {};
size_t parent_stack_count = 0;
for (; section_stack_count;) {
DN_INISection const *it = section_stack[--section_stack_count];
if (it != &ini->first_section) {
DN_INI_Str8BuilderAppend(&builder, "[");
for (DN_INISection *parent = it->parent; parent; parent = parent->parent)
if (parent->name.size)
parent_stack[parent_stack_count++] = parent;
for (size_t index = parent_stack_count - 1; index < parent_stack_count; index--) {
DN_INISection *parent = parent_stack[index];
DN_INI_Str8BuilderAppend(&builder, "%.*s.", (int)parent->name.size, parent->name.data);
}
parent_stack_count = 0;
DN_INI_Str8BuilderAppend(&builder, "%.*s]\n", (int)it->name.size, it->name.data);
}
for (DN_INIField *field = it->first_field; field; field = field->next) {
DN_INI_Str8BuilderAppend(&builder, "%.*s = ", (int)field->key.size, field->key.data);
switch (field->value_type) {
case DN_INIFieldType_String: DN_INI_Str8BuilderAppend(&builder, "%.*s\n", (int)field->value.size, field->value.data); break;
case DN_INIFieldType_Bool: DN_INI_Str8BuilderAppend(&builder, "%d\n", field->value_bool); break;
case DN_INIFieldType_USize: DN_INI_Str8BuilderAppend(&builder, "%zu\n", field->value_usize); break;
}
}
if (it->next)
section_stack[section_stack_count++] = it->next;
if (it->child_first)
section_stack[section_stack_count++] = it->child_first;
if (section_stack_count)
DN_INI_Str8BuilderAppend(&builder, "\n");
}
result.size_req = builder.size_req;
if (buffer) {
result.str8.data = builder.data;
result.str8.size = builder.used;
result.success = true;
} else {
result.success = true;
}
return result;
}
#if defined(DN_INI_WITH_UNIT_TESTS) || 1
void DN_INI_UnitTests()
{
+26 -23
View File
@@ -153,34 +153,37 @@ struct DN_INIFieldBool
// NOTE: Utilities
int DN_INI_SNPrintF_ (char const *buffer, size_t size, char const *fmt, ...);
void * DN_INI_ArenaAlloc (DN_INIArena *arena, size_t size);
DN_INIStr8 DN_INI_Str8FromPtr (char const *data, size_t count);
// Str8FromINI's `size` parameter must include space for the null-terminator, i.e:
// `DN_INIStr8FromResult.size_req + 1` bytes
int DN_INI_SNPrintF_ (char const *buffer, size_t size, char const *fmt, ...);
void * DN_INI_ArenaAlloc (DN_INIArena *arena, size_t size);
DN_INIStr8 DN_INI_Str8FromPtr (char const *data, size_t count);
DN_INIStr8FromResult DN_INI_Str8FromINI (DN_INICore const *ini, char *buffer, size_t size);
// NOTE: Tokeniser/Parsing
DN_INITokeniser DN_INI_TokeniserFromPtr (char const *buf, size_t count);
DN_INIToken DN_INI_NextToken (DN_INITokeniser const *tokeniser);
void DN_INI_EatToken (DN_INITokeniser *tokeniser, DN_INIToken token);
DN_INITokeniser DN_INI_TokeniserFromPtr (char const *buf, size_t count);
DN_INIToken DN_INI_NextToken (DN_INITokeniser const *tokeniser);
void DN_INI_EatToken (DN_INITokeniser *tokeniser, DN_INIToken token);
// NOTE: Lookup
DN_INISection * DN_INI_ChildSectionFromStr8 (DN_INISection *section, DN_INIStr8 str8);
DN_INISection * DN_INI_ChildSectionFromCStr (DN_INISection *section, char const *name, size_t name_size);
DN_INIField * DN_INI_FieldFromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
DN_INIField * DN_INI_FieldFromSection (DN_INISection *section, char const *key, size_t key_size);
DN_INIFieldUSize DN_INI_FieldUSizeFromSectionStr8(DN_INISection *section, DN_INIStr8 str8);
DN_INIFieldStr8 DN_INI_FieldStr8FromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
DN_INIFieldBool DN_INI_FieldBoolFromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
DN_INICore DN_INI_ParseFromPtr (char const *buf, size_t count, char *base, size_t base_count);
DN_INISection * DN_INI_ChildSectionFromStr8 (DN_INISection *section, DN_INIStr8 str8);
DN_INISection * DN_INI_ChildSectionFromCStr (DN_INISection *section, char const *name, size_t name_size);
DN_INIField * DN_INI_FieldFromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
DN_INIField * DN_INI_FieldFromSection (DN_INISection *section, char const *key, size_t key_size);
DN_INIFieldUSize DN_INI_FieldUSizeFromSectionStr8(DN_INISection *section, DN_INIStr8 str8);
DN_INIFieldStr8 DN_INI_FieldStr8FromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
DN_INIFieldBool DN_INI_FieldBoolFromSectionStr8 (DN_INISection *section, DN_INIStr8 str8);
DN_INICore DN_INI_ParseFromPtr (char const *buf, size_t count, char *base, size_t base_count);
// NOTE: Building
DN_INISection * DN_INI_AppendSectionF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *fmt, ...);
DN_INIField * DN_INI_AppendKeyBool (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, bool value);
DN_INIField * DN_INI_AppendKeyPtrBool (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, bool value);
DN_INIField * DN_INI_AppendKeyUSize (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, size_t value);
DN_INIField * DN_INI_AppendKeyPtrUSize (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, size_t value);
DN_INIField * DN_INI_AppendKeyCStr8 (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *value, size_t value_size);
DN_INIField * DN_INI_AppendKeyF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *fmt, ...);
void DN_INI_AppendField (DN_INISection *section, DN_INIField *field);
// NOTE: Building
DN_INISection * DN_INI_AppendSectionF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *fmt, ...);
DN_INIField * DN_INI_AppendKeyBool (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, bool value);
DN_INIField * DN_INI_AppendKeyPtrBool (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, bool value);
DN_INIField * DN_INI_AppendKeyUSize (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, size_t value);
DN_INIField * DN_INI_AppendKeyPtrUSize (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, char const *key, size_t key_size, size_t value);
DN_INIField * DN_INI_AppendKeyCStr8 (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *value, size_t value_size);
DN_INIField * DN_INI_AppendKeyF (DN_INICore *ini, DN_INIArena *arena, DN_INISection *section, DN_INIStr8 key, char const *fmt, ...);
void DN_INI_AppendField (DN_INISection *section, DN_INIField *field);
#if defined(DN_INI_WITH_UNIT_TESTS)
void DN_INI_UnitTests ();