Format code

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-07-26 00:22:28 +03:00
parent 90a6e58dca
commit ae8d2907fc
3 changed files with 950 additions and 890 deletions

26
.clang-format Normal file
View File

@@ -0,0 +1,26 @@
UseTab: ForIndentation
TabWidth: 4
IndentWidth: 4
ColumnLimit: 80
AlignEscapedNewlines: DontAlign
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
BasedOnStyle: WebKit
BraceWrapping:
AfterFunction: true
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: true
BreakConstructorInitializers: BeforeComma
IndentPPDirectives: AfterHash
IndentRequiresClause: false
InsertNewlineAtEOF: true
LineEnding: LF
NamespaceIndentation: None
PointerAlignment: Right # east pointer
QualifierAlignment: Right # east const
RemoveSemicolon: true
RequiresClausePosition: WithFollowing
RequiresExpressionIndentation: OuterScope
SpaceAfterTemplateKeyword: false

View File

@@ -57,23 +57,22 @@ char const *dcfg_last_error(dcfg_Instance *instance);
// File path gets copied internally to instance to a Value * -> path hashmap for
// evaluation.
dcfg_Value *dcfg_parse(dcfg_Instance *instance,
dcfg_StringView const file_path);
dcfg_Value *dcfg_parse(
dcfg_Instance *instance, dcfg_StringView const file_path);
void dcfg_destroy(dcfg_Value *value);
bool dcfg_serialize_value(dcfg_Value *value, dcfg_StringView *out_sv);
// Value type checking
dcfg_ValueType dcfg_Value_type_ex(dcfg_Value *value, bool evaluate);
static inline dcfg_ValueType dcfg_Value_type(dcfg_Value *value) {
static inline dcfg_ValueType dcfg_Value_type(dcfg_Value *value)
{
return dcfg_Value_type_ex(value, true);
}
// Value getters
bool dcfg_Value_get_object_field_ex(dcfg_Value *value,
dcfg_StringView const key,
dcfg_Value **out_value,
bool const evaluate);
dcfg_StringView const key, dcfg_Value **out_value, bool const evaluate);
bool dcfg_Value_get_array_item_ex(dcfg_Value *value, size_t const index,
dcfg_Value **out_value, bool const evaluate);
@@ -86,14 +85,14 @@ bool dcfg_Value_get_object_keys(dcfg_Value *value, size_t const capacity,
size_t *out_count, dcfg_StringView *out_keys);
bool dcfg_Value_get_array_size(dcfg_Value *value, size_t *out_size);
static inline bool dcfg_Value_get_object_field(dcfg_Value *value,
dcfg_StringView const key,
dcfg_Value **out_value) {
static inline bool dcfg_Value_get_object_field(
dcfg_Value *value, dcfg_StringView const key, dcfg_Value **out_value)
{
return dcfg_Value_get_object_field_ex(value, key, out_value, true);
}
static inline bool dcfg_Value_get_array_item(dcfg_Value *value,
size_t const index,
dcfg_Value **out_value) {
static inline bool dcfg_Value_get_array_item(
dcfg_Value *value, size_t const index, dcfg_Value **out_value)
{
return dcfg_Value_get_array_item_ex(value, index, out_value, true);
}

View File

@@ -5,13 +5,13 @@
#include "vendor/vec.h"
#ifdef DCFG_POSIX_SUPPORT
#ifdef __sun
# ifdef __sun
// FIXME: Fix this stupid shit!
#error "realpath() is dumb and stupid on sun. sorry not sorry."
#endif
#define _XOPEN_SOURCE 200809L
# error "realpath() is dumb and stupid on sun. sorry not sorry."
# endif
# define _XOPEN_SOURCE 200809L
#else
#define _POSIX_C_SOURCE 0L
# define _POSIX_C_SOURCE 0L
#endif
#include <assert.h>
@@ -21,7 +21,7 @@
#include <string.h>
#ifdef DCFG_PTHREAD_SUPPORT
#include <pthread.h>
# include <pthread.h>
#else
typedef struct {
int unused;
@@ -33,7 +33,8 @@ void pthread_mutex_lock(pthread_mutex_t *);
void pthread_mutex_unlock(pthread_mutex_t *);
#endif
int64_t dcfg_strtoll(const char *s, char **end, int base) {
int64_t dcfg_strtoll(const char *s, char **end, int base)
{
size_t n = strlen(s);
char *clean = malloc(n + 1);
if (!clean) {
@@ -66,7 +67,8 @@ int64_t dcfg_strtoll(const char *s, char **end, int base) {
return v;
}
double dcfg_strtod(const char *s, char **end) {
double dcfg_strtod(char const *s, char **end)
{
size_t n = strlen(s);
char *clean = malloc(n + 1);
if (!clean) {
@@ -103,9 +105,10 @@ typedef dcfg_Value Value;
typedef dcfg_Instance Instance;
typedef dcfg_StringView StringView;
#define SV(cstr) ((StringView){.data = cstr, .size = strlen(cstr)})
#define SV(cstr) ((StringView) { .data = cstr, .size = strlen(cstr) })
static inline bool sv_eq(StringView a, StringView b) {
static inline bool sv_eq(StringView a, StringView b)
{
if (a.size != b.size) {
return false;
}
@@ -199,7 +202,8 @@ int fseek_(void *f, size_t p, int o) { return fseek(f, p, o); }
long ftell_(void *f) { return ftell(f); }
#endif
dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info) {
dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info)
{
assert(create_info);
dcfg_Instance *instance = calloc(1, sizeof(*instance));
@@ -241,7 +245,8 @@ dcfg_Instance *dcfg_make_instance(dcfg_InstanceCreateInfo const *create_info) {
return instance;
}
void dcfg_destroy_instance(dcfg_Instance *instance) {
void dcfg_destroy_instance(dcfg_Instance *instance)
{
assert(instance);
pthread_mutex_lock(&instance->mtx);
@@ -254,7 +259,8 @@ void dcfg_destroy_instance(dcfg_Instance *instance) {
free(instance);
}
char const *dcfg_last_error(dcfg_Instance *instance) {
char const *dcfg_last_error(dcfg_Instance *instance)
{
assert(instance);
char const *ret = NULL;
@@ -314,35 +320,40 @@ typedef struct {
int offset;
} Lexer;
static inline int32_t decode_cp(StringView src, int pos, int *len) {
static inline int32_t decode_cp(StringView src, int pos, int *len)
{
if (pos >= (int)src.size) {
*len = 0;
return -1;
}
return (int32_t)utf8proc_iterate((const uint8_t *)src.data + pos,
(int)(src.size - pos), len);
return (int32_t)utf8proc_iterate(
(uint8_t const *)src.data + pos, (int)(src.size - pos), len);
}
static inline bool is_space_cp(int32_t cp) {
return (cp <= 0x7F &&
(cp == ' ' || cp == '\t' || cp == '\r' || cp == '\n')) ||
utf8proc_category(cp) == UTF8PROC_CATEGORY_ZS;
static inline bool is_space_cp(int32_t cp)
{
return (cp <= 0x7F && (cp == ' ' || cp == '\t' || cp == '\r' || cp == '\n'))
|| utf8proc_category(cp) == UTF8PROC_CATEGORY_ZS;
}
static inline bool is_alpha_cp(int32_t cp) {
return (cp <= 0x7F && isalpha(cp)) ||
(utf8proc_category(cp) >= UTF8PROC_CATEGORY_LU &&
utf8proc_category(cp) <= UTF8PROC_CATEGORY_LO);
static inline bool is_alpha_cp(int32_t cp)
{
return (cp <= 0x7F && isalpha(cp))
|| (utf8proc_category(cp) >= UTF8PROC_CATEGORY_LU
&& utf8proc_category(cp) <= UTF8PROC_CATEGORY_LO);
}
static inline bool is_digit_cp(int32_t cp) {
return (cp <= 0x7F && isdigit(cp)) ||
utf8proc_category(cp) == UTF8PROC_CATEGORY_ND;
static inline bool is_digit_cp(int32_t cp)
{
return (cp <= 0x7F && isdigit(cp))
|| utf8proc_category(cp) == UTF8PROC_CATEGORY_ND;
}
static inline bool is_alnum_cp(int32_t cp) {
static inline bool is_alnum_cp(int32_t cp)
{
return is_alpha_cp(cp) || is_digit_cp(cp);
}
static inline bool is_path_ch_cp(int32_t cp) {
return cp == '_' || cp == '.' || cp == '/' || cp == '-' || cp == ':' ||
is_alnum_cp(cp);
static inline bool is_path_ch_cp(int32_t cp)
{
return cp == '_' || cp == '.' || cp == '/' || cp == '-' || cp == ':'
|| is_alnum_cp(cp);
}
#define is_space is_space_cp
@@ -351,7 +362,8 @@ static inline bool is_path_ch_cp(int32_t cp) {
#define isdigit_cp is_digit_cp
#define isalnum_cp is_alnum_cp
static void lex_advance(Lexer *lx) {
static void lex_advance(Lexer *lx)
{
if (lx->next == -1) {
lx->ch = -1;
return;
@@ -370,14 +382,16 @@ static void lex_advance(Lexer *lx) {
lx->next = decode_cp(lx->source, lx->offset + lx->ch_len, &lx->next_len);
}
static StringView lex_slice(Lexer *lx, int start, int end) {
static StringView lex_slice(Lexer *lx, int start, int end)
{
StringView sv;
sv.data = lx->source.data + start;
sv.size = (size_t)(end - start);
return sv;
}
static void skip_ws_and_comments(Lexer *lx) {
static void skip_ws_and_comments(Lexer *lx)
{
for (;;) {
while (is_space(lx->ch))
lex_advance(lx);
@@ -390,8 +404,9 @@ static void skip_ws_and_comments(Lexer *lx) {
}
}
static Token make_token(TokenType t, Lexer *lx, int start, int end) {
Token tk = {0};
static Token make_token(TokenType t, Lexer *lx, int start, int end)
{
Token tk = { 0 };
tk.type = t;
tk.location.fp = lx->fp;
tk.location.range.begin = lx->cursor;
@@ -419,7 +434,8 @@ static Token make_token(TokenType t, Lexer *lx, int start, int end) {
return tk;
}
static Token lex_number(Lexer *lx) {
static Token lex_number(Lexer *lx)
{
int start = lx->offset;
bool real = false;
@@ -431,18 +447,20 @@ static Token lex_number(Lexer *lx) {
while (isdigit_cp(lx->ch) || lx->ch == '_')
lex_advance(lx);
}
return make_token(real ? TokenType_Real : TokenType_Integer, lx, start,
lx->offset);
return make_token(
real ? TokenType_Real : TokenType_Integer, lx, start, lx->offset);
}
static Token lex_identifier(Lexer *lx) {
static Token lex_identifier(Lexer *lx)
{
int start = lx->offset;
while (isalnum_cp(lx->ch) || lx->ch == '_')
lex_advance(lx);
return make_token(TokenType_Identifier, lx, start, lx->offset);
}
static Token lex_string(Lexer *lx) {
static Token lex_string(Lexer *lx)
{
int quote = lx->ch;
lex_advance(lx); // skip opening quote
int start = lx->offset;
@@ -457,7 +475,8 @@ static Token lex_string(Lexer *lx) {
return make_token(TokenType_String, lx, start, end);
}
static Token lex_path(Lexer *lx) {
static Token lex_path(Lexer *lx)
{
int start = lx->offset;
for (;;) {
if (lx->ch == '\\') {
@@ -472,32 +491,34 @@ static Token lex_path(Lexer *lx) {
return make_token(TokenType_Path, lx, start, lx->offset);
}
bool Lexer_init(Lexer *lx, StringView src, StringView fp) {
bool Lexer_init(Lexer *lx, StringView src, StringView fp)
{
memset(lx, 0, sizeof *lx);
lx->source = src;
lx->fp = fp;
lx->cursor = (Location){1, 1};
lx->cursor = (Location) { 1, 1 };
lx->ch = decode_cp(src, 0, &lx->ch_len);
lx->next = decode_cp(src, lx->ch_len, &lx->next_len);
return true;
}
Token Lexer_next(Lexer *lx) {
Token Lexer_next(Lexer *lx)
{
skip_ws_and_comments(lx);
int start_off = lx->offset;
if (lx->ch == -1) {
Token tk = {.type = TokenType_End};
Token tk = { .type = TokenType_End };
tk.location.fp = lx->fp;
return tk;
}
if (lx->ch == '/' // "/foo"
|| (lx->ch == '.' && lx->next == '/') // "./foo"
|| (lx->ch == '.' && lx->offset + 2 < (int)lx->source.size &&
lx->source.data[lx->offset + 1] == '.' &&
lx->source.data[lx->offset + 2] == '/') // "../foo"
|| (lx->ch == '.' && lx->offset + 2 < (int)lx->source.size
&& lx->source.data[lx->offset + 1] == '.'
&& lx->source.data[lx->offset + 2] == '/') // "../foo"
|| (isalpha_cp(lx->ch) && lx->next == ':')) { // "C:/foo"
return lex_path(lx);
}
@@ -539,7 +560,7 @@ Token Lexer_next(Lexer *lx) {
if (isdigit_cp(lx->ch))
return lex_number(lx);
Token err = {.type = TokenType_Error};
Token err = { .type = TokenType_Error };
err.location.fp = lx->fp;
lex_advance(lx);
return err;
@@ -611,7 +632,8 @@ typedef struct {
Token cur, next;
} Parser;
bool Parser_next(Parser *parser) {
bool Parser_next(Parser *parser)
{
parser->cur = parser->next;
parser->next = Lexer_next(parser->lexer);
bool ret = parser->next.type != TokenType_Error;
@@ -621,7 +643,8 @@ bool Parser_next(Parser *parser) {
return ret;
}
bool Parser_init(Parser *out_parser, Lexer *lexer, Instance *instance) {
bool Parser_init(Parser *out_parser, Lexer *lexer, Instance *instance)
{
out_parser->lexer = lexer;
out_parser->instance = instance;
if (!Parser_next(out_parser)) {
@@ -633,8 +656,8 @@ bool Parser_init(Parser *out_parser, Lexer *lexer, Instance *instance) {
return true;
}
bool Parser_accept(Parser *parser, TokenType type,
SourceLocation *out_location) {
bool Parser_accept(Parser *parser, TokenType type, SourceLocation *out_location)
{
if (parser->cur.type == type) {
if (out_location) {
*out_location = parser->cur.location;
@@ -652,7 +675,8 @@ bool Parser_accept(Parser *parser, TokenType type,
#define ALLOC(sz) (parser->instance->alloc((sz)))
#define FREE(ptr) (parser->instance->free((ptr)))
void AST_free_parser(AST *ast, Parser *parser) {
void AST_free_parser(AST *ast, Parser *parser)
{
assert(parser);
if (!ast) {
return;
@@ -691,10 +715,11 @@ void AST_free_parser(AST *ast, Parser *parser) {
FREE(ast);
}
AST *parser_parse_dot_access(Parser *parser, StringView *current) {
AST *parser_parse_dot_access(Parser *parser, StringView *current)
{
assert(parser);
assert(parser->cur.type == TokenType_Identifier ||
parser->cur.type == TokenType_String);
assert(parser->cur.type == TokenType_Identifier
|| parser->cur.type == TokenType_String);
StringView *accessv = vector_create();
if (!accessv) {
@@ -708,8 +733,8 @@ AST *parser_parse_dot_access(Parser *parser, StringView *current) {
SourceLocation loc = parser->cur.location;
SourceLocation last_loc = parser->cur.location;
while (true) {
if (parser->cur.type != TokenType_Identifier &&
parser->cur.type != TokenType_String) {
if (parser->cur.type != TokenType_Identifier
&& parser->cur.type != TokenType_String) {
break;
}
@@ -745,7 +770,8 @@ AST *parser_parse_dot_access(Parser *parser, StringView *current) {
return ast;
}
AST *parser_parse_value(Parser *parser) {
AST *parser_parse_value(Parser *parser)
{
AST *ast = ALLOC(sizeof(*ast));
ast->location = parser->cur.location;
if (parser->cur.type == TokenType_Integer) {
@@ -754,8 +780,8 @@ AST *parser_parse_value(Parser *parser) {
} else if (parser->cur.type == TokenType_Real) {
ast->kind = ASTKind_Real;
ast->v.r = parser->cur.v.r;
} else if (parser->cur.type == TokenType_String ||
parser->cur.type == TokenType_Identifier) {
} else if (parser->cur.type == TokenType_String
|| parser->cur.type == TokenType_Identifier) {
ast->kind = ASTKind_Key;
ast->v.s = parser->cur.v.s;
@@ -765,7 +791,8 @@ AST *parser_parse_value(Parser *parser) {
} else if (parser->cur.type == TokenType_Identifier) {
if (sv_eq(ast->v.s, SV("fn"))) {
if (!Parser_next(parser)) {
strcpy(parser->instance->last_error, "Failed to advance fn keyword");
strcpy(parser->instance->last_error,
"Failed to advance fn keyword");
FREE(ast);
return NULL;
}
@@ -773,7 +800,8 @@ AST *parser_parse_value(Parser *parser) {
ast->kind = ASTKind_Function;
ast->v.f.argv = vector_create();
if (!ast->v.f.argv) {
strcpy(parser->instance->last_error, "Failed to allocate vector");
strcpy(parser->instance->last_error,
"Failed to allocate vector");
FREE(ast);
return NULL;
}
@@ -802,10 +830,12 @@ AST *parser_parse_value(Parser *parser) {
}
ast->location.range.end = ast->v.f.body->location.range.end;
return ast;
} else if (sv_eq(ast->v.s, SV("on")) || sv_eq(ast->v.s, SV("true"))) {
} else if (sv_eq(ast->v.s, SV("on"))
|| sv_eq(ast->v.s, SV("true"))) {
ast->kind = ASTKind_Boolean;
ast->v.b = true;
} else if (sv_eq(ast->v.s, SV("off")) || sv_eq(ast->v.s, SV("false"))) {
} else if (sv_eq(ast->v.s, SV("off"))
|| sv_eq(ast->v.s, SV("false"))) {
ast->kind = ASTKind_Boolean;
ast->v.b = false;
}
@@ -854,8 +884,8 @@ AST *parser_parse_value(Parser *parser) {
break;
}
if (parser->cur.type != TokenType_Identifier &&
parser->cur.type != TokenType_String) {
if (parser->cur.type != TokenType_Identifier
&& parser->cur.type != TokenType_String) {
strcpy(parser->instance->last_error,
"Expected identifier or string for object key");
vector_free(ast->v.bl.entryv);
@@ -865,7 +895,8 @@ AST *parser_parse_value(Parser *parser) {
AST *key = parser_parse_dot_access(parser, NULL);
if (!Parser_accept(parser, TokenType_Set, NULL)) {
strcpy(parser->instance->last_error, "Expected = after object key");
strcpy(parser->instance->last_error,
"Expected = after object key");
vector_free(ast->v.bl.entryv);
FREE(ast);
return NULL;
@@ -879,7 +910,8 @@ AST *parser_parse_value(Parser *parser) {
return NULL;
}
assert(key->kind == ASTKind_MemberAccess || key->kind == ASTKind_Key);
assert(
key->kind == ASTKind_MemberAccess || key->kind == ASTKind_Key);
ASTBlock_Entry entry = {
.k = key,
.v = value,
@@ -921,7 +953,8 @@ AST *parser_parse_value(Parser *parser) {
return ast;
} else {
if (parser->cur.type == TokenType_End) {
strcpy(parser->instance->last_error, "Expected value, got end of file");
strcpy(parser->instance->last_error,
"Expected value, got end of file");
} else {
strcpy(parser->instance->last_error, "Unexpected token for value");
}
@@ -945,7 +978,8 @@ AST *Parser_parse(Parser *parser) { return parser_parse_value(parser); }
#define ALLOC(sz) (instance->alloc((sz)))
#define FREE(ptr) (instance->free((ptr)))
Value *ast_to_value(dcfg_Instance *instance, AST *root) {
Value *ast_to_value(dcfg_Instance *instance, AST *root)
{
Value *value = ALLOC(sizeof(*value));
value->instance = instance;
if (root->kind == ASTKind_Key) {
@@ -1028,8 +1062,8 @@ Value *ast_to_value(dcfg_Instance *instance, AST *root) {
return value;
}
dcfg_Value *dcfg_parse(dcfg_Instance *instance,
dcfg_StringView const file_path) {
dcfg_Value *dcfg_parse(dcfg_Instance *instance, dcfg_StringView const file_path)
{
char path_buf[file_path.size + 1] = {};
memcpy(path_buf, file_path.data, file_path.size);
@@ -1112,7 +1146,8 @@ dcfg_Value *dcfg_parse(dcfg_Instance *instance,
return v;
}
void dcfg_destroy(dcfg_Value *value) {
void dcfg_destroy(dcfg_Value *value)
{
(void)value;
// FIXME: Implement
}