meta refactorings

This commit is contained in:
Krzosa Karol
2025-01-20 11:00:33 +01:00
parent 6f53fa4db0
commit f221ccfcf9
10 changed files with 268 additions and 266 deletions

125
src/meta/meta_cfiles.c Normal file
View File

@@ -0,0 +1,125 @@
typedef struct mt_file_t mt_file_t;
struct mt_file_t {
mt_file_t *next;
s8_t path;
s8_t content;
lex_array_t tokens;
};
typedef struct mt_files_t mt_files_t;
struct mt_files_t {
mt_file_t *first;
mt_file_t *last;
};
fn s8_t mt_resolve_path(ma_arena_t *arena, sb8_t *include_paths, s8_t filename, s8_t parent_file, b32 is_system_include) {
if (OS_IsAbsolute(filename) && os_file_exists(filename)) {
return filename;
}
// 1) (QUOTED_FORM) In the same directory as the file that contains the #include statement.
if (!is_system_include && parent_file.len) {
s8_t path = s8_printf(arena, "%S/%S", s8_chop_last_slash(parent_file), filename);
if (os_file_exists(path)) {
return OS_GetAbsolutePath(&Perm, path);
}
}
// 2) (QUOTED FORM) In the directories of the currently opened include files, in the reverse order in which they were opened. The search begins in the directory of the parent include file and continues upward through the directories of any grandparent include files.
// 3) (BOTH FORMS) Along the path that's specified by each /I (or INCLUDE enviroment variable) compiler option.
for (sb8_node_t *it = include_paths->first; it; it = it->next) {
s8_t path = s8_printf(arena, "%S/%S", it->string, filename);
if (os_file_exists(path)) {
return OS_GetAbsolutePath(&Perm, path);
}
}
return s8_null;
}
fn mt_file_t *mt_find_file_exact(mt_files_t *root, s8_t path) {
for (mt_file_t *it = root->first; it; it = it->next) {
if (s8_are_equal(path, it->path)) return it;
}
return NULL;
}
fn mt_file_t *mt_find_file(mt_files_t *root, s8_t name) {
for (mt_file_t *it = root->first; it; it = it->next) {
if (s8_ends_with(name, it->path, false)) return it;
}
return NULL;
}
fn void mt__lex_files(ma_arena_t *arena, mt_files_t *root, s8_t path, sb8_t *include_paths) {
s8_t content = OS_ReadFile(&Perm, path);
if (content.len == 0) {
return;
}
lex_array_t array = lex_tokens(arena, path.str, content);
mt_file_t *file = ma_push_type(arena, mt_file_t);
file->tokens = array;
file->content = content;
file->path = path;
SLLQ_APPEND(root->first, root->last, file);
for (i32 i = 0; i < array.len; i += 1) {
lex_t *token = array.data + i;
if (token->kind != lex_kind_preproc_include) {
continue;
}
s8_t inc_path = mt_resolve_path(arena, include_paths, token->string, s8_from_char(token->file), token->system_include);
if (inc_path.len && mt_find_file_exact(root, inc_path) == NULL) {
// debugf("%s:%d %S, %S", token->file, token->line + 1, token->string, inc_path);
mt__lex_files(arena, root, inc_path, include_paths);
}
}
}
fn mt_files_t mt_lex_files(ma_arena_t *arena, s8_t path, sb8_t *include_paths) {
mt_files_t files = {0};
path = OS_GetAbsolutePath(&Perm, path);
mt__lex_files(arena, &files, path, include_paths);
return files;
}
fn void mt_list_files_recursive(sb8_t *sb, s8_t path) {
for (OS_FileIter iter = OS_IterateFiles(&Perm, path); OS_IsValid(iter); OS_Advance(&iter)) {
if (iter.is_directory) {
mt_list_files_recursive(sb, iter.absolute_path);
} else {
sb8_append(sb, iter.absolute_path);
}
}
}
fn void mt_serial_to_cbyte_array_ex(sb8_t *sb, s8_t file, s8_t var_name) {
sb8_printf(sb, "u8 %S[] = {", var_name);
for (i64 i = 0; i < file.len; i += 1) {
if ((i % 64) == 0) sb8_printf(sb, "\n");
u8 byte = *(u8 *)(file.str + i);
sb8_printf(sb, "%u,", byte);
}
sb8_printf(sb, "\n};\n");
}
fn s8_t mt_serial_to_cbyte_array(ma_arena_t *arena, s8_t file, s8_t var_name) {
ma_temp_t scratch = ma_begin_scratch1(arena);
sb8_t *sb = sb8_serial_begin(scratch.arena);
mt_serial_to_cbyte_array_ex(sb, file, var_name);
s8_t result = sb8_serial_end(arena, sb);
ma_end_scratch(scratch);
return result;
}
#define mt_cpath(arena) mt_gen_filename(arena, s8_lit(__FILE__), s8_lit("c"))
#define mt_hpath(arena) mt_gen_filename(arena, s8_lit(__FILE__), s8_lit("h"))
fn s8_t mt_gen_filename(ma_arena_t *arena, s8_t lit_file, s8_t ext) {
s8_t file_noext = s8_chop_last_period(s8_chop_last_period(lit_file));
s8_t file = s8_printf(arena, "%S.gen.%S", file_noext, ext);
return file;
}