File utilities and datatype implementation for a C-based code generator (#5)
Co-authored-by: Abdelrahman Said <said.abdelrahman@flawlessai.com> Reviewed-on: #5 Co-authored-by: Abdelrahman <said.abdelrahman89@gmail.com> Co-committed-by: Abdelrahman <said.abdelrahman89@gmail.com>
This commit is contained in:
103
src/core/file/file.c
Normal file
103
src/core/file/file.c
Normal file
@@ -0,0 +1,103 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#include "file.h"
|
||||
#include "../os/cpath/cpath.h"
|
||||
#include "../../common/assert/assert.h"
|
||||
#include "../../common/aliases/aliases.h"
|
||||
#include "../../primitives/array/array.h"
|
||||
#include "../../primitives/strings/str8/str8.h"
|
||||
#include <stdio.h>
|
||||
|
||||
File *wapp_file_open(Str8RO *filepath, FileAccessMode mode) {
|
||||
persistent const char *modes[FILE_ACCESS_MODE_COUNT] = {
|
||||
[WAPP_FA_MODE_R] = "r",
|
||||
[WAPP_FA_MODE_W] = "w",
|
||||
[WAPP_FA_MODE_A] = "a",
|
||||
[WAPP_FA_MODE_R_EX] = "r+",
|
||||
[WAPP_FA_MODE_W_EX] = "w+",
|
||||
[WAPP_FA_MODE_A_EX] = "a+",
|
||||
[WAPP_FA_MODE_RB] = "rb",
|
||||
[WAPP_FA_MODE_WB] = "wb",
|
||||
[WAPP_FA_MODE_AB] = "ab",
|
||||
[WAPP_FA_MODE_RB_EX] = "rb+",
|
||||
[WAPP_FA_MODE_WB_EX] = "wb+",
|
||||
[WAPP_FA_MODE_AB_EX] = "ab+",
|
||||
[WAPP_FA_MODE_WX] = "wx",
|
||||
[WAPP_FA_MODE_WX_EX] = "wx+",
|
||||
[WAPP_FA_MODE_WBX] = "wbx",
|
||||
[WAPP_FA_MODE_WBX_EX] = "wbx+",
|
||||
};
|
||||
persistent c8 tmp[WAPP_PATH_MAX] = {0};
|
||||
wapp_debug_assert(filepath->size < WAPP_PATH_MAX, "`filepath` exceeds max path limit.");
|
||||
|
||||
memset(tmp, 0, WAPP_PATH_MAX);
|
||||
memcpy(tmp, filepath->buf, filepath->size);
|
||||
|
||||
return fopen((const char *)tmp, modes[mode]);
|
||||
}
|
||||
|
||||
u64 wapp_file_get_current_position(File *file) {
|
||||
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
|
||||
return (u64)ftell(file);
|
||||
}
|
||||
|
||||
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin) {
|
||||
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
|
||||
return fseek(file, offset, origin);
|
||||
}
|
||||
|
||||
u64 wapp_file_get_length(File *file) {
|
||||
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
|
||||
|
||||
u64 current = wapp_file_get_current_position(file);
|
||||
|
||||
wapp_file_seek(file, 0, WAPP_SEEK_END);
|
||||
|
||||
u64 output = ftell(file);
|
||||
|
||||
// Restore position
|
||||
wapp_file_seek(file, current, WAPP_SEEK_START);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
u64 wapp_file_read(GenericArray *dst, File *file, u64 item_count) {
|
||||
wapp_debug_assert(dst != NULL && dst->items != NULL && file != NULL,
|
||||
"`dst`, `dst->items` and `file` should not be NULL.");
|
||||
|
||||
u64 file_length = wapp_file_get_length(file);
|
||||
u64 dst_byte_capacity = dst->item_size * dst->capacity;
|
||||
u64 req_byte_count = item_count * dst->item_size;
|
||||
u64 copy_byte_count = 0;
|
||||
|
||||
if (req_byte_count <= file_length && req_byte_count <= dst_byte_capacity) {
|
||||
copy_byte_count = req_byte_count;
|
||||
} else {
|
||||
copy_byte_count = file_length <= dst_byte_capacity ? file_length : dst_byte_capacity;
|
||||
}
|
||||
|
||||
dst->count = fread(dst->items, sizeof(u8), copy_byte_count, file) / dst->item_size;
|
||||
|
||||
return dst->count;
|
||||
}
|
||||
|
||||
u64 wapp_file_write(const GenericArray *src, File *file, u64 item_count) {
|
||||
wapp_debug_assert(src != NULL && src->items != NULL && file != NULL,
|
||||
"`src`, `src->items` and `file` should not be NULL.");
|
||||
|
||||
u64 src_byte_count = src->count * src->item_size;
|
||||
u64 req_byte_count = item_count * src->item_size;
|
||||
u64 to_copy = req_byte_count <= src_byte_count ? req_byte_count : src_byte_count;
|
||||
|
||||
return fwrite(src->items, sizeof(u8), to_copy, file);
|
||||
}
|
||||
|
||||
i32 wapp_file_flush(File *file) {
|
||||
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
|
||||
return fflush(file);
|
||||
}
|
||||
|
||||
i32 wapp_file_close(File *file) {
|
||||
wapp_debug_assert(file != NULL, "`file` should not be NULL.");
|
||||
return fclose(file);
|
||||
}
|
72
src/core/file/file.h
Normal file
72
src/core/file/file.h
Normal file
@@ -0,0 +1,72 @@
|
||||
// vim:fileencoding=utf-8:foldmethod=marker
|
||||
|
||||
#ifndef FILE_H
|
||||
#define FILE_H
|
||||
|
||||
#include "../../common/aliases/aliases.h"
|
||||
#include "../../primitives/array/array.h"
|
||||
#include "../../primitives/strings/str8/str8.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
BEGIN_C_LINKAGE
|
||||
#endif // !WAPP_PLATFORM_CPP
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
#define wapp_file_item_to_array(ITEM) (GenericArray{&(ITEM), 1, 1, sizeof(ITEM)})
|
||||
#define wapp_file_array_to_item(TYPE, ARRAY) (sizeof(TYPE) == (ARRAY).item_size && (ARRAY).count == 1 ? \
|
||||
*((TYPE *)((ARRAY).items)) : \
|
||||
TYPE{})
|
||||
#else
|
||||
#define wapp_file_item_to_array(ITEM) ((GenericArray){.items = &(ITEM), \
|
||||
.count = 1, \
|
||||
.capacity = 1, \
|
||||
.item_size = sizeof(ITEM)})
|
||||
#define wapp_file_array_to_item(TYPE, ARRAY) (sizeof(TYPE) == (ARRAY).item_size && (ARRAY).count == 1 ? \
|
||||
*((TYPE *)((ARRAY).items)) : \
|
||||
(TYPE){0})
|
||||
#endif // !WAPP_PLATFORM_CPP
|
||||
|
||||
typedef FILE File;
|
||||
|
||||
typedef enum {
|
||||
WAPP_FA_MODE_R, // Equivalent to r
|
||||
WAPP_FA_MODE_W, // Equivalent to w
|
||||
WAPP_FA_MODE_A, // Equivalent to a
|
||||
WAPP_FA_MODE_R_EX, // Equivalent to r+
|
||||
WAPP_FA_MODE_W_EX, // Equivalent to w+
|
||||
WAPP_FA_MODE_A_EX, // Equivalent to a+
|
||||
WAPP_FA_MODE_RB, // Equivalent to rb
|
||||
WAPP_FA_MODE_WB, // Equivalent to wb
|
||||
WAPP_FA_MODE_AB, // Equivalent to ab
|
||||
WAPP_FA_MODE_RB_EX, // Equivalent to rb+
|
||||
WAPP_FA_MODE_WB_EX, // Equivalent to wb+
|
||||
WAPP_FA_MODE_AB_EX, // Equivalent to ab+
|
||||
WAPP_FA_MODE_WX, // Equivalent to wx
|
||||
WAPP_FA_MODE_WX_EX, // Equivalent to wx+
|
||||
WAPP_FA_MODE_WBX, // Equivalent to wbx
|
||||
WAPP_FA_MODE_WBX_EX, // Equivalent to wbx+
|
||||
|
||||
FILE_ACCESS_MODE_COUNT,
|
||||
} FileAccessMode;
|
||||
|
||||
typedef enum {
|
||||
WAPP_SEEK_START = SEEK_SET,
|
||||
WAPP_SEEK_CURRENT = SEEK_CUR,
|
||||
WAPP_SEEK_END = SEEK_END,
|
||||
} FileSeekOrigin;
|
||||
|
||||
File *wapp_file_open(Str8RO *filename, FileAccessMode mode);
|
||||
u64 wapp_file_get_current_position(File *file);
|
||||
i32 wapp_file_seek(File *file, u64 offset, FileSeekOrigin origin);
|
||||
u64 wapp_file_get_length(File *file);
|
||||
u64 wapp_file_read(GenericArray *dst, File *file, u64 item_count);
|
||||
u64 wapp_file_write(const GenericArray *src, File *file, u64 item_count);
|
||||
i32 wapp_file_flush(File *file);
|
||||
i32 wapp_file_close(File *file);
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
END_C_LINKAGE
|
||||
#endif // !WAPP_PLATFORM_CPP
|
||||
|
||||
#endif // !FILE_H
|
@@ -6,7 +6,6 @@
|
||||
#include "../../../common/assert/assert.h"
|
||||
#include "../../../common/misc/misc_utils.h"
|
||||
#include "../../os/mem/mem_os.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -22,14 +21,14 @@ struct arena {
|
||||
u8 *buf;
|
||||
u8 *offset;
|
||||
u64 capacity;
|
||||
bool committed;
|
||||
b32 committed;
|
||||
|
||||
#ifdef WAPP_PLATFORM_WINDOWS
|
||||
wapp_misc_utils_padding_size(sizeof(u8 *) * 2 + sizeof(u64) + sizeof(bool));
|
||||
wapp_misc_utils_padding_size(sizeof(u8 *) * 2 + sizeof(u64) + sizeof(b32));
|
||||
#endif // ifdef WAPP_PLATFORM_WINDOWS
|
||||
};
|
||||
|
||||
bool wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, bool zero_buffer) {
|
||||
b32 wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b32 zero_buffer) {
|
||||
if (!arena || *arena || base_capacity == 0) {
|
||||
return false;
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@
|
||||
#include "../../../common/aliases/aliases.h"
|
||||
#include "../../../common/platform/platform.h"
|
||||
#include "../../os/mem/mem_os.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
BEGIN_C_LINKAGE
|
||||
@@ -28,7 +27,7 @@ typedef struct arena Arena;
|
||||
* control over how the Arena is initialised. Wrapper macros are provided for
|
||||
* easier use.
|
||||
*/
|
||||
bool wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, bool zero_buffer);
|
||||
b32 wapp_mem_arena_init_custom(Arena **arena, u64 base_capacity, MemAllocFlags flags, b32 zero_buffer);
|
||||
void *wapp_mem_arena_alloc(Arena *arena, u64 size);
|
||||
void *wapp_mem_arena_alloc_aligned(Arena *arena, u64 size, u64 alignment);
|
||||
void *wapp_mem_arena_realloc(Arena *arena, void *ptr, u64 old_size, u64 new_size);
|
||||
|
@@ -12,9 +12,9 @@ internal inline void *mem_arena_realloc_aligned(void *ptr, u64 old_size, u64 new
|
||||
void *alloc_obj);
|
||||
|
||||
|
||||
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, bool zero_buffer) {
|
||||
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b32 zero_buffer) {
|
||||
Allocator allocator = {0};
|
||||
bool initialised = wapp_mem_arena_init_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer);
|
||||
b32 initialised = wapp_mem_arena_init_custom((Arena **)(&allocator.obj), base_capacity, flags, zero_buffer);
|
||||
if (!initialised) {
|
||||
return allocator;
|
||||
}
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#include "../../../common/platform/platform.h"
|
||||
#include "../../../primitives/mem_allocator/mem_allocator.h"
|
||||
#include "../../os/mem/mem_os.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
BEGIN_C_LINKAGE
|
||||
@@ -33,7 +32,7 @@ BEGIN_C_LINKAGE
|
||||
* The `wapp_mem_arena_allocator_init_custom` provides the most control over how
|
||||
* the Arena is initialised. Wrapper macros are provided for easier use.
|
||||
*/
|
||||
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, bool zero_buffer);
|
||||
Allocator wapp_mem_arena_allocator_init_custom(u64 base_capacity, MemAllocFlags flags, b32 zero_buffer);
|
||||
void wapp_mem_arena_allocator_clear(Allocator *allocator);
|
||||
void wapp_mem_arena_allocator_destroy(Allocator *allocator);
|
||||
|
||||
|
@@ -3,10 +3,9 @@
|
||||
#include "mem_utils.h"
|
||||
#include "../../../common/aliases/aliases.h"
|
||||
#include "../../../common/assert/assert.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
internal bool is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
|
||||
internal b32 is_power_of_two(u64 num) { return (num & (num - 1)) == 0; }
|
||||
|
||||
void *wapp_mem_util_align_forward(void *ptr, u64 alignment) {
|
||||
wapp_debug_assert(ptr != NULL, "`ptr` should not be NULL");
|
||||
|
@@ -8,7 +8,6 @@
|
||||
#include "../../../primitives/mem_allocator/mem_allocator.h"
|
||||
#include "../../../primitives/strings/str8/str8.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -22,7 +21,7 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
|
||||
}
|
||||
|
||||
Str8 separator = wapp_str8_buf(4);
|
||||
wapp_str8_push_back(&separator, PATH_SEP);
|
||||
wapp_str8_push_back(&separator, WAPP_PATH_SEP);
|
||||
|
||||
u64 required_capacity = parts->node_count * separator.size + wapp_str8_list_total_size(parts);
|
||||
if (dst->capacity < required_capacity) {
|
||||
@@ -37,7 +36,7 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
|
||||
// MSVC Spectre mitigation warnings
|
||||
const Str8Node *node = first_node;
|
||||
u64 node_index = 1;
|
||||
bool running = node_index < parts->node_count;
|
||||
b32 running = node_index < parts->node_count;
|
||||
while (running && node->next) {
|
||||
node = node->next;
|
||||
if (node->item->size == 0) {
|
||||
@@ -45,9 +44,9 @@ u32 wapp_cpath_join_path(Str8 *dst, const Str8List *parts) {
|
||||
}
|
||||
|
||||
if (dst->size > 0) {
|
||||
char dst_last = wapp_str8_get(dst, dst->size - 1);
|
||||
char node_start = wapp_str8_get(node->item, 0);
|
||||
bool add_path_sep = dst_last != PATH_SEP && node_start != PATH_SEP;
|
||||
char dst_last = wapp_str8_get(dst, dst->size - 1);
|
||||
char node_start = wapp_str8_get(node->item, 0);
|
||||
b32 add_path_sep = dst_last != WAPP_PATH_SEP && node_start != WAPP_PATH_SEP;
|
||||
|
||||
if (add_path_sep) {
|
||||
wapp_str8_concat_capped(dst, &separator);
|
||||
@@ -69,9 +68,9 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
bool absolute = wapp_str8_get(path, 0) == PATH_SEP;
|
||||
b32 absolute = wapp_str8_get(path, 0) == WAPP_PATH_SEP;
|
||||
Str8 separator = wapp_str8_buf(4);
|
||||
wapp_str8_push_back(&separator, PATH_SEP);
|
||||
wapp_str8_push_back(&separator, WAPP_PATH_SEP);
|
||||
|
||||
if (path->size == 0) {
|
||||
output = wapp_str8_alloc_buf(allocator, 16);
|
||||
@@ -79,7 +78,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
|
||||
wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.');
|
||||
goto RETURN_DIRUP;
|
||||
}
|
||||
|
||||
@@ -104,7 +103,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
|
||||
goto LIST_CLEANUP_DIRUP;
|
||||
}
|
||||
|
||||
wapp_str8_push_back(output, absolute ? PATH_SEP : '.');
|
||||
wapp_str8_push_back(output, absolute ? WAPP_PATH_SEP : '.');
|
||||
} else {
|
||||
for (u64 i = 0; i < levels; ++i) {
|
||||
wapp_str8_list_pop_back(parts);
|
||||
@@ -118,7 +117,7 @@ Str8 *dirup(const Allocator *allocator, Str8RO *path, u64 levels) {
|
||||
output = wapp_str8_alloc_buf(allocator, alloc_size);
|
||||
if (output) {
|
||||
if (absolute) {
|
||||
wapp_str8_push_back(output, PATH_SEP);
|
||||
wapp_str8_push_back(output, WAPP_PATH_SEP);
|
||||
}
|
||||
|
||||
Str8 *joined = wapp_str8_join(&tmp_arena, parts, &separator);
|
||||
|
@@ -13,9 +13,13 @@ BEGIN_C_LINKAGE
|
||||
#endif // !WAPP_PLATFORM_CPP
|
||||
|
||||
#ifdef WAPP_PLATFORM_POSIX
|
||||
#define PATH_SEP '/'
|
||||
#include <limits.h>
|
||||
#define WAPP_PATH_SEP '/'
|
||||
#define WAPP_PATH_MAX PATH_MAX
|
||||
#elif defined(WAPP_PLATFORM_WINDOWS)
|
||||
#define PATH_SEP '\\'
|
||||
#include <windows.h>
|
||||
#define WAPP_PATH_SEP '\\'
|
||||
#define WAPP_PATH_MAX MAX_PATH
|
||||
#else
|
||||
#error "Unrecognised platform"
|
||||
#endif
|
||||
|
@@ -5,7 +5,6 @@
|
||||
#include "../../../common/aliases/aliases.h"
|
||||
#include "../../../common/platform/platform.h"
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(WAPP_PLATFORM_WINDOWS)
|
||||
|
@@ -10,7 +10,6 @@
|
||||
#include "../../../../primitives/mem_allocator/mem_allocator.h"
|
||||
#include "../../../../primitives/strings/str8/str8.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@@ -7,7 +7,6 @@
|
||||
#include "../../../../common/aliases/aliases.h"
|
||||
#include "../../../../common/platform/platform.h"
|
||||
#include "../../../../primitives/strings/str8/str8.h"
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@@ -5,7 +5,6 @@
|
||||
|
||||
#include "../../../../common/aliases/aliases.h"
|
||||
#include "../../../../common/platform/platform.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef WAPP_PLATFORM_CPP
|
||||
BEGIN_C_LINKAGE
|
||||
@@ -30,11 +29,11 @@ typedef struct commander_result CMDResult;
|
||||
struct commander_result {
|
||||
i32 exit_code;
|
||||
CMDError error;
|
||||
bool exited;
|
||||
b32 exited;
|
||||
|
||||
#ifdef WAPP_PLATFORM_WINDOWS
|
||||
#include "../../../../common/misc/misc_utils.h"
|
||||
wapp_misc_utils_padding_size(sizeof(bool) + sizeof(i32) + sizeof(CMDError));
|
||||
wapp_misc_utils_padding_size(sizeof(b32) + sizeof(i32) + sizeof(CMDError));
|
||||
#endif // !WAPP_PLATFORM_WINDOWS
|
||||
};
|
||||
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#define WAPP_CORE_C
|
||||
|
||||
#include "wapp_core.h"
|
||||
#include "file/file.c"
|
||||
#include "os/shell/termcolour/posix/termcolour_posix.c"
|
||||
#include "os/shell/termcolour/win/termcolour_win.c"
|
||||
#include "os/shell/termcolour/termcolour.c"
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#ifndef WAPP_CORE_H
|
||||
#define WAPP_CORE_H
|
||||
|
||||
#include "file/file.h"
|
||||
#include "os/shell/termcolour/termcolour.h"
|
||||
#include "os/shell/termcolour/terminal_colours.h"
|
||||
#include "os/shell/commander/commander.h"
|
||||
|
Reference in New Issue
Block a user