diff options
author | dec05eba <dec05eba@protonmail.com> | 2019-03-10 16:52:53 +0100 |
---|---|---|
committer | dec05eba <dec05eba@protonmail.com> | 2020-07-25 14:36:46 +0200 |
commit | 79bf40f909cefdc611bfa13f70ae55b52ac41d23 (patch) | |
tree | a022cbf8e0548aab677aabb5a9138619cb9aa562 /src/std | |
parent | 470a60a3ea8723852568df2ecf7587303b250664 (diff) |
Load @import files relative to the file that uses @import
Diffstat (limited to 'src/std')
-rw-r--r-- | src/std/file.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/src/std/file.c b/src/std/file.c index 46099b4..098b18f 100644 --- a/src/std/file.c +++ b/src/std/file.c @@ -14,6 +14,7 @@ #include <unistd.h> #define SCANDIR_PATH_LENGTH 4096 +#define MAX_FILE_SIZE 1024*1024*48 /* 48 mb */ static int scan_dir_recursive_internal(char *dir_path, int path_length, scan_dir_callback_func callback_func, void *userdata) { DIR *dir; @@ -165,11 +166,40 @@ int mapped_file_deinit(MappedFile *self) { return 0; } +typedef enum { + REGULAR, + DIRECTORY, + OTHER +} FileType; + +static CHECK_RESULT int file_get_type(const char *filepath, FileType *type) { + struct stat file_stats; + if(stat(filepath, &file_stats) == -1) { + amal_log_perror(filepath); + return -1; + } + + if(file_stats.st_mode & S_IFDIR) + *type = DIRECTORY; + else if(file_stats.st_mode & S_IFREG) + *type = REGULAR; + else + *type = OTHER; + return 0; +} + int read_whole_file(const char *filepath, char **data, usize *size) { + FileType file_type; FILE *file; int result; usize bytes_read; + return_if_error(file_get_type(filepath, &file_type)); + if(file_type != REGULAR) { + amal_log_error("Expected file %s to be a regular file", filepath); + return -2; + } + result = 0; file = fopen(filepath, "rb"); if(!file) { @@ -192,6 +222,12 @@ int read_whole_file(const char *filepath, char **data, usize *size) { goto cleanup; } + if(*size > MAX_FILE_SIZE) { + amal_log_error("File %s is too large (larger than 48 megabytes)", filepath); + result = -1; + goto cleanup; + } + cleanup_if_error(am_malloc(*size, (void**)data)); bytes_read = fread(*data, 1, *size, file); if(bytes_read != *size) { @@ -202,3 +238,21 @@ int read_whole_file(const char *filepath, char **data, usize *size) { fclose(file); return result; } + +BufferView file_get_parent_directory(BufferView filepath) { + int i; + for(i = filepath.size - 1; i >= 0; --i) { + if(filepath.data[i] == '/') + return create_buffer_view(filepath.data, i); + } + return create_buffer_view(filepath.data, 0); +} + +BufferView file_get_name(BufferView filepath) { + int i; + for(i = filepath.size - 1; i >= 0; --i) { + if(filepath.data[i] == '/') + return create_buffer_view(filepath.data + i, filepath.size - i); + } + return filepath; +} |